Merge "qca-wifi: Updating CFR's DBR handler API"
diff --git a/dp/inc/dp_rate_stats.h b/dp/inc/dp_rate_stats.h
new file mode 100644
index 0000000..c9bd589
--- /dev/null
+++ b/dp/inc/dp_rate_stats.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * @file: dp_rate_stats.h
+ * @brief: Define peer rate statistics related objects and APIs
+ */
+
+#ifndef _DP_RATE_STATS_
+#define _DP_RATE_STATS_
+
+#include <cdp_txrx_handle.h>
+#include <qdf_nbuf.h>
+#include <wdi_event_api.h>
+
+#ifdef QCA_SUPPORT_RDK_STATS
+
+#include <qdf_util.h>
+#include <cdp_txrx_cmn_struct.h>
+#include <cdp_txrx_cmn.h>
+#include <dp_ratetable.h>
+#include <dp_rate_stats_pub.h>
+
+#define RATE_STATS_LOCK_CREATE(lock) qdf_spinlock_create(lock)
+#define RATE_STATS_LOCK_DESTROY(lock) qdf_spinlock_destroy(lock)
+#define RATE_STATS_LOCK_ACQUIRE(lock) qdf_spin_lock_bh(lock)
+#define RATE_STATS_LOCK_RELEASE(lock) qdf_spin_unlock_bh(lock)
+
+struct cdp_pdev;
+
+/**
+ * struct wlan_peer_tx_rate_stats - peer tx rate statistics
+ * @stats: array containing tx rate stats
+ * @cur_rix: rate index updated last in list
+ * @lock: lock protecting list
+ * @sojourn: sojourn statistics
+ */
+struct wlan_peer_tx_rate_stats {
+	struct wlan_tx_rate_stats stats[WLANSTATS_CACHE_SIZE];
+	struct wlan_tx_sojourn_stats sojourn;
+	uint32_t cur_rix;
+	uint8_t cur_cache_idx;
+	qdf_spinlock_t lock;
+};
+
+/**
+ * struct wlan_peer_rx_rate_stats - Peer Rx rate statistics
+ * @stats: array containing rx rate stats
+ * @cur_rix: rate index updated last in list
+ * @lock: lock protecting list
+ */
+struct wlan_peer_rx_rate_stats {
+	struct wlan_rx_rate_stats stats[WLANSTATS_CACHE_SIZE];
+	uint32_t cur_rix;
+	uint32_t cur_cache_idx;
+	qdf_spinlock_t lock;
+};
+
+/**
+ * struct wlan_peer_rate_stats - Peer rate statistics ctx
+ * @tx: tx rate statistics
+ * @rx: rx rate statistics
+ * @mac_addr: peer MAC address
+ * @peer_cookie: cookie for unique session of peer
+ * @pdev: dp pdev
+ */
+struct wlan_peer_rate_stats_ctx {
+	struct wlan_peer_tx_rate_stats tx;
+	struct wlan_peer_rx_rate_stats rx;
+	uint8_t mac_addr[WLAN_MAC_ADDR_LEN];
+	uint64_t peer_cookie;
+	struct cdp_pdev *pdev;
+};
+
+/**
+ * struct wlan_soc_rate_stats_ctx - rate stats context at soc level
+ * @soc: Opaque soc handle
+ * @txs_cache_flush: tx stats flush count
+ * @rxs_cache_flush: rx stats flush count
+ * @txs_last_idx_cache_hit: cache hit for rate index received as last rate index
+ * @txs_cache_hit: tx stats cache hit for rate index received from cache db
+ * @rxs_last_idx_cache_hit: cache hit for rate index received as last rate index
+ * @rxs_cache_hit: cache hit for rate index received from cache database
+ * @txs_cache_miss: rate index recevied is not in cache database
+ * @rxs_cache_miss: rate index recevied is not in cache database
+ */
+struct wlan_soc_rate_stats_ctx {
+	struct cdp_soc_t *soc;
+	uint32_t txs_cache_flush;
+	uint32_t rxs_cache_flush;
+	uint32_t txs_last_idx_cache_hit;
+	uint32_t txs_cache_hit;
+	uint32_t rxs_last_idx_cache_hit;
+	uint32_t rxs_cache_hit;
+	uint32_t txs_cache_miss;
+	uint32_t rxs_cache_miss;
+};
+
+/**
+ * wlan_peer_update_rate_stats ()- WDI handler to update rate stats
+ * @ctx: soc level stats context
+ * @event: WDI event enum
+ * @stats: buffer containing cdp_peer_tx_rate_stats_intf or
+ * cdp_peer_rx_rate_stats_intf
+ * @peer_id: peer id
+ * @type: enum wlan_rate_stats_type
+ */
+
+void wlan_peer_update_rate_stats(void *ctx,
+				 enum WDI_EVENT event,
+				 void *stats, uint16_t peer_id,
+				 uint32_t type);
+
+/**
+ * wlan_cfg80211_flush_rate_stats ()- os_if layer handler to
+ * flush rate statistics
+ * @pdev: Ctrl pdev
+ * @event: WDI event enum
+ * @ptr: Stats buffer
+ * @peer_id: peer id
+ * @status: status
+ */
+void wlan_cfg80211_flush_rate_stats(void *ctrl_pdev, enum WDI_EVENT event,
+				    void *ptr, uint16_t peer_id,
+				    uint32_t status);
+
+/**
+ * wlan_peer_create_event_handler ()- peer create event handler
+ * to initialize statistics objects
+ * @pdev: Ctrl pdev
+ * @event: WDI event enum
+ * @peer_mac: Peer MAC address
+ * @buf: Stats buffer
+ * @peer_id: peer id
+ * @status: status
+ */
+void wlan_peer_create_event_handler(void *pdev, enum WDI_EVENT event,
+				    void *buf, uint16_t peer_id,
+				    uint32_t status);
+
+/**
+ * wlan_peer_destroy_event_handler ()- peer destroy event handler
+ * to deinitilize statistics objects
+ * @pdev: Ctrl pdev
+ * @event: WDI event enum
+ * @peer_mac: Peer MAC address
+ * @buf: Stats buffer
+ * @peer_id: peer id
+ * @status: status
+ */
+void wlan_peer_destroy_event_handler(void *pdev, enum WDI_EVENT event,
+				     void *buf, uint16_t peer_id,
+				     uint32_t status);
+
+/**
+ * wlan_peer_rate_stats_flush_req ()- stats flush request event handler
+ * This flushes statistics to user space entity
+ * @pdev: Ctrl pdev
+ * @event: WDI event enum
+ * @buf: Stats buffer
+ * @peer_id: peer id
+ * @status: status
+ */
+void wlan_peer_rate_stats_flush_req(void *pdev, enum WDI_EVENT event,
+				    void *buf, uint16_t peer_id,
+				    uint32_t status);
+
+#else
+static inline void
+wlan_peer_update_rate_stats(void *pdev, enum WDI_EVENT event,
+			    void *stats, uint16_t peer_id,
+			    uint32_t type)
+{
+}
+
+static inline void
+wlan_cfg80211_flush_rate_stats(void *ctrl_pdev, enum WDI_EVENT event,
+			       void *ptr, uint16_t peer_id,
+			       uint32_t status)
+{
+}
+
+static inline void
+wlan_peer_create_event_handler(void *pdev, enum WDI_EVENT event,
+			       void *buf, uint16_t peer_id,
+			       uint32_t type)
+{
+}
+
+static inline void
+wlan_peer_destroy_event_handler(void *pdev, enum WDI_EVENT event,
+				void *buf, uint16_t peer_id,
+				uint32_t type)
+{
+}
+
+static inline void
+wlan_peer_rate_stats_flush_req(void *pdev,
+			       enum WDI_EVENT event,
+			       void *buf, uint16_t peer_id,
+			       uint32_t type)
+{
+}
+#endif /* QCA_SUPPORT_RDK_STATS */
+#endif /* _DP_RATE_STATS_ */
diff --git a/dp/inc/dp_rate_stats_pub.h b/dp/inc/dp_rate_stats_pub.h
new file mode 100644
index 0000000..b46708e
--- /dev/null
+++ b/dp/inc/dp_rate_stats_pub.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * @file: dp_rate_stats_pub.h
+ * @breief: Define peer rate statistics related objects and APIs
+ * accessed required for user space tools
+ */
+
+#ifndef _DP_RATE_STATS_UAPI_
+#define _DP_RATE_STATS_UAPI_
+
+#define WLANSTATS_CACHE_SIZE 10
+#define MAX_RSSI_ANT 4
+#define MAX_RSSI_HT 4
+#define WLAN_DATA_TID_MAX 8
+#define WLAN_MAC_ADDR_LEN 6
+#define WLANSTATS_RSSI_OFFSET 8
+#define WLANSTATS_RSSI_MASK 0xff
+#define WLANSTATS_RSSI_MAX 0x80
+
+#ifndef __KERNEL__
+#define qdf_ewma_tx_lag int
+#define qdf_ewma_rx_rssi int
+#else
+#include <cdp_txrx_cmn_struct.h>
+QDF_DECLARE_EWMA(rx_rssi, 1024, 8)
+#endif
+
+/**
+ * enum cdp_peer_rate_stats_cmd -
+ * used by app to get specific stats
+ */
+enum wlan_peer_rate_stats_cmd {
+	DP_PEER_RX_RATE_STATS,
+	DP_PEER_TX_RATE_STATS,
+	DP_PEER_SOJOURN_STATS,
+};
+
+/** struct wlan_tx_rate_stats - Tx packet rate info
+ * @rix: Rate index derived from nss, mcs, preamble, ht, sgi
+ * @rate: Data rate in kbps
+ * @mpdu_success: success mpdus count
+ * @mpdu_attempts: attempt mpdus count
+ * @num_ppdus: ppdu count
+ */
+struct wlan_tx_rate_stats {
+	uint32_t rix;
+	uint32_t rate;
+	uint32_t mpdu_success;
+	uint32_t mpdu_attempts;
+	uint32_t num_ppdus;
+};
+
+/** struct wlan_rx_rate_stats - Rx rate packet info
+ * @rix: Rate index derived from nss, mcs, preamble, ht, sgi
+ * @rate: Data rate in kbps
+ * @num_bytes: num of bytes
+ * @num_msdus: num of msdus
+ * @num_mpdus: num of mpdus
+ * @num_ppdus: num of ppdus
+ * @num_retries: num of retries
+ * @num_sgi: num of short guard interval
+ */
+struct wlan_rx_rate_stats {
+	uint32_t rix;
+	uint32_t rate;
+	uint32_t num_bytes;
+	uint32_t num_msdus;
+	uint32_t num_mpdus;
+	uint32_t num_ppdus;
+	uint32_t num_retries;
+	uint32_t num_sgi;
+	qdf_ewma_rx_rssi avg_rssi;
+	qdf_ewma_rx_rssi avg_rssi_ant[MAX_RSSI_ANT][MAX_RSSI_HT];
+};
+
+/*
+ * struct wlan_tx_sojourn_stats - Tx sojourn stats
+ * @ppdu_seq_id: ppdu_seq_id from tx completion
+ * @avg_sojourn_msdu: average sojourn msdu time
+ * @sum_sojourn_msdu: sum sojourn msdu time
+ * @num_msdu: number of msdus per ppdu
+ * @cookie: cookie to be used by upper layer
+ */
+struct wlan_tx_sojourn_stats {
+	uint32_t ppdu_seq_id;
+	qdf_ewma_tx_lag avg_sojourn_msdu[WLAN_DATA_TID_MAX];
+	uint32_t sum_sojourn_msdu[WLAN_DATA_TID_MAX];
+	uint32_t num_msdus[WLAN_DATA_TID_MAX];
+	void *cookie;
+};
+
+/**
+ * struct wlan_peer_rate_stats_intf - Interface structure to
+ * flush stats to user spave entity
+ * @stats: statistics buffer
+ * @buf_len: buffer len
+ * @peer_mac: peer mac address
+ * @stats_type: statistics type
+ * @cookie: peer cookie
+ */
+struct wlan_peer_rate_stats_intf {
+	void *stats;
+	uint32_t buf_len;
+	uint8_t peer_mac[WLAN_MAC_ADDR_LEN];
+	uint8_t stats_type;
+	uint64_t cookie;
+};
+#endif /* _DP_RATE_STATS_UAPI_ */
diff --git a/dp/src/dp_rate_stats.c b/dp/src/dp_rate_stats.c
new file mode 100644
index 0000000..50c1017
--- /dev/null
+++ b/dp/src/dp_rate_stats.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * @file: dp_rate_stats.c
+ * @breief: Core peer rate statistics processing module
+ */
+
+#include "dp_rate_stats.h"
+#include "dp_rate_stats_pub.h"
+
+#ifdef QCA_SUPPORT_RDK_STATS
+
+static void
+wlan_peer_flush_rx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
+			      struct wlan_peer_rate_stats_ctx *stats_ctx)
+{
+	struct wlan_peer_rate_stats_intf buf;
+	struct wlan_peer_rx_rate_stats *rx_stats;
+
+	if (!soc_stats_ctx)
+		return;
+	rx_stats = &stats_ctx->rx;
+
+	buf.stats = (struct wlan_rx_rate_stats *)rx_stats->stats;
+	buf.buf_len = WLANSTATS_CACHE_SIZE * sizeof(struct wlan_rx_rate_stats);
+	buf.stats_type = DP_PEER_RX_RATE_STATS;
+	buf.cookie = stats_ctx->peer_cookie;
+	qdf_mem_copy(buf.peer_mac, stats_ctx->mac_addr, WLAN_MAC_ADDR_LEN);
+	cdp_peer_flush_rate_stats(soc_stats_ctx->soc,
+				  stats_ctx->pdev, &buf);
+
+	soc_stats_ctx->rxs_cache_flush++;
+	qdf_info("rxs_cache_flush: %d", soc_stats_ctx->rxs_cache_flush);
+
+	qdf_mem_zero(rx_stats->stats, WLANSTATS_CACHE_SIZE *
+		     sizeof(struct wlan_rx_rate_stats));
+}
+
+static void
+wlan_peer_flush_tx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
+			      struct wlan_peer_rate_stats_ctx *stats_ctx)
+{
+	struct wlan_peer_rate_stats_intf buf;
+	struct wlan_peer_tx_rate_stats *tx_stats;
+
+	if (!soc_stats_ctx)
+		return;
+
+	tx_stats = &stats_ctx->tx;
+	buf.stats = (struct wlan_tx_rate_stats *)tx_stats->stats;
+	buf.buf_len = (WLANSTATS_CACHE_SIZE * sizeof(struct wlan_tx_rate_stats)
+		       + sizeof(struct wlan_tx_sojourn_stats));
+	buf.stats_type = DP_PEER_TX_RATE_STATS;
+	buf.cookie = stats_ctx->peer_cookie;
+	qdf_mem_copy(buf.peer_mac, stats_ctx->mac_addr, WLAN_MAC_ADDR_LEN);
+	cdp_peer_flush_rate_stats(soc_stats_ctx->soc,
+				  stats_ctx->pdev, &buf);
+
+	soc_stats_ctx->txs_cache_flush++;
+	qdf_info("txs_cache_flush: %d", soc_stats_ctx->txs_cache_flush);
+
+	qdf_mem_zero(tx_stats->stats, WLANSTATS_CACHE_SIZE *
+		     sizeof(struct wlan_tx_rate_stats) +
+		     sizeof(struct wlan_tx_sojourn_stats));
+}
+
+static void
+wlan_peer_flush_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
+			   struct wlan_peer_rate_stats_ctx *stats_ctx)
+{
+	struct wlan_peer_tx_rate_stats *tx_stats;
+	struct wlan_peer_rx_rate_stats *rx_stats;
+
+	tx_stats = &stats_ctx->tx;
+	rx_stats = &stats_ctx->rx;
+
+	RATE_STATS_LOCK_ACQUIRE(&tx_stats->lock);
+	wlan_peer_flush_tx_rate_stats(soc_stats_ctx, stats_ctx);
+	RATE_STATS_LOCK_RELEASE(&tx_stats->lock);
+
+	RATE_STATS_LOCK_ACQUIRE(&rx_stats->lock);
+	wlan_peer_flush_rx_rate_stats(soc_stats_ctx, stats_ctx);
+	RATE_STATS_LOCK_RELEASE(&rx_stats->lock);
+}
+
+void wlan_peer_rate_stats_flush_req(void *ctx, enum WDI_EVENT event,
+				    void *buf, uint16_t peer_id,
+				    uint32_t type)
+{
+	if (buf)
+		wlan_peer_flush_rate_stats(ctx, buf);
+}
+
+static inline void
+__wlan_peer_update_rx_rate_stats(struct wlan_rx_rate_stats *__rx_stats,
+				 struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
+{
+	uint8_t ant, ht;
+
+	__rx_stats->rix = cdp_rx_ppdu->rix;
+	__rx_stats->rate = cdp_rx_ppdu->rx_ratekbps;
+	__rx_stats->num_bytes += cdp_rx_ppdu->num_bytes;
+	__rx_stats->num_msdus += cdp_rx_ppdu->num_msdu;
+	__rx_stats->num_mpdus += cdp_rx_ppdu->num_mpdu;
+	__rx_stats->num_retries += cdp_rx_ppdu->retries;
+	__rx_stats->num_ppdus += 1;
+
+	if (cdp_rx_ppdu->u.gi)
+		__rx_stats->num_sgi++;
+
+	qdf_ewma_rx_rssi_add(&__rx_stats->avg_rssi, cdp_rx_ppdu->rssi);
+
+	for (ant = 0; ant < MAX_RSSI_ANT; ant++) {
+		for (ht = 0; ht < MAX_RSSI_HT; ht++)
+			qdf_ewma_rx_rssi_add(&__rx_stats->avg_rssi_ant[ant][ht],
+					     cdp_rx_ppdu->rssi_chain[ant][ht]);
+	}
+}
+
+static void
+wlan_peer_update_rx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
+			       struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
+{
+	struct wlan_peer_rate_stats_ctx *stats_ctx;
+	struct wlan_peer_rx_rate_stats *rx_stats;
+	struct wlan_rx_rate_stats *__rx_stats;
+	uint8_t cache_idx;
+	bool idx_match = false;
+
+	stats_ctx = (struct wlan_peer_rate_stats_ctx *)cdp_rx_ppdu->cookie;
+
+	if (qdf_unlikely(!stats_ctx)) {
+		qdf_warn("peer rate stats ctx is NULL, return");
+		qdf_warn("peer_mac:  " QDF_MAC_ADDR_STR,
+			 QDF_MAC_ADDR_ARRAY(cdp_rx_ppdu->mac_addr));
+		return;
+	}
+
+	rx_stats = &stats_ctx->rx;
+
+	if (qdf_unlikely(cdp_rx_ppdu->rix > DP_RATE_TABLE_SIZE)) {
+		qdf_warn("Invalid rate index, return");
+		return;
+	}
+
+	RATE_STATS_LOCK_ACQUIRE(&rx_stats->lock);
+	if (qdf_likely(rx_stats->cur_rix == cdp_rx_ppdu->rix)) {
+		__rx_stats = &rx_stats->stats[rx_stats->cur_cache_idx];
+		__wlan_peer_update_rx_rate_stats(__rx_stats,
+						 cdp_rx_ppdu);
+
+		soc_stats_ctx->rxs_last_idx_cache_hit++;
+		goto done;
+	}
+
+	/* check if cache is available */
+	for (cache_idx = 0; cache_idx < WLANSTATS_CACHE_SIZE; cache_idx++) {
+		__rx_stats = &rx_stats->stats[cache_idx];
+		if (!__rx_stats->rix || (__rx_stats->rix == cdp_rx_ppdu->rix)) {
+			idx_match = true;
+			break;
+		}
+	}
+	/* if index matches or found empty index, update stats to that
+	 * cache index else flush cache and update stats to cache index zero
+	 */
+	if (idx_match) {
+		__wlan_peer_update_rx_rate_stats(__rx_stats,
+						 cdp_rx_ppdu);
+		rx_stats->cur_rix = cdp_rx_ppdu->rix;
+		rx_stats->cur_cache_idx = cache_idx;
+		soc_stats_ctx->rxs_cache_hit++;
+		goto done;
+	} else {
+		wlan_peer_flush_rx_rate_stats(soc_stats_ctx, stats_ctx);
+		__rx_stats = &rx_stats->stats[0];
+		__wlan_peer_update_rx_rate_stats(__rx_stats,
+						 cdp_rx_ppdu);
+		rx_stats->cur_rix = cdp_rx_ppdu->rix;
+		rx_stats->cur_cache_idx = 0;
+		soc_stats_ctx->rxs_cache_miss++;
+	}
+done:
+	RATE_STATS_LOCK_RELEASE(&rx_stats->lock);
+}
+
+static inline void
+__wlan_peer_update_tx_rate_stats(struct wlan_tx_rate_stats *__tx_stats,
+				 struct cdp_tx_completion_ppdu_user *ppdu_user)
+{
+	uint8_t num_ppdus;
+	uint8_t mpdu_attempts;
+	uint8_t mpdu_success;
+
+	num_ppdus = ppdu_user->long_retries + 1;
+	mpdu_attempts = num_ppdus * ppdu_user->mpdu_tried_ucast;
+	mpdu_success = ppdu_user->mpdu_tried_ucast - ppdu_user->mpdu_failed;
+
+	__tx_stats->rix = ppdu_user->rix;
+	__tx_stats->rate = ppdu_user->tx_rate;
+	__tx_stats->num_ppdus += num_ppdus;
+	__tx_stats->mpdu_attempts += mpdu_attempts;
+	__tx_stats->mpdu_success += mpdu_success;
+}
+
+static void
+wlan_peer_update_tx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
+			       struct cdp_tx_completion_ppdu *cdp_tx_ppdu)
+{
+	struct cdp_tx_completion_ppdu_user *ppdu_user;
+	struct wlan_peer_rate_stats_ctx *stats_ctx;
+	struct wlan_peer_tx_rate_stats *tx_stats;
+	struct wlan_tx_rate_stats *__tx_stats;
+	uint8_t cache_idx;
+	uint8_t user_idx;
+	bool idx_match = false;
+
+	for (user_idx = 0; user_idx < cdp_tx_ppdu->num_users; user_idx++) {
+		ppdu_user = &cdp_tx_ppdu->user[user_idx];
+		stats_ctx = (struct wlan_peer_rate_stats_ctx *)
+				ppdu_user->cookie;
+
+		if (qdf_unlikely(!stats_ctx)) {
+			qdf_warn("peer rate stats ctx is NULL, return");
+			qdf_warn("peer_mac: " QDF_MAC_ADDR_STR,
+				 QDF_MAC_ADDR_ARRAY(ppdu_user->mac_addr));
+			return;
+		}
+
+		tx_stats = &stats_ctx->tx;
+		RATE_STATS_LOCK_ACQUIRE(&tx_stats->lock);
+
+		if (qdf_unlikely(ppdu_user->rix > DP_RATE_TABLE_SIZE)) {
+			qdf_warn("Invalid rate index, continue.");
+			RATE_STATS_LOCK_RELEASE(&tx_stats->lock);
+			continue;
+		}
+		if (qdf_likely(tx_stats->cur_rix == ppdu_user->rix)) {
+			__tx_stats = &tx_stats->stats[tx_stats->cur_cache_idx];
+			__wlan_peer_update_tx_rate_stats(__tx_stats, ppdu_user);
+			soc_stats_ctx->txs_last_idx_cache_hit++;
+			RATE_STATS_LOCK_RELEASE(&tx_stats->lock);
+			continue;
+		}
+
+		/* check if cache is available */
+		for (cache_idx = 0; cache_idx < WLANSTATS_CACHE_SIZE;
+					cache_idx++) {
+			__tx_stats = &tx_stats->stats[cache_idx];
+			if (!__tx_stats->rix ||
+			    (__tx_stats->rix == ppdu_user->rix)) {
+				idx_match = true;
+				break;
+			}
+		}
+		/* if index matches or found empty index,
+		 * update stats to that cache index
+		 * else flush cache and update stats to cache index zero
+		 */
+		if (idx_match) {
+			soc_stats_ctx->txs_cache_hit++;
+
+			__wlan_peer_update_tx_rate_stats(__tx_stats,
+							 ppdu_user);
+			tx_stats->cur_rix = ppdu_user->rix;
+			tx_stats->cur_cache_idx = cache_idx;
+		} else {
+			soc_stats_ctx->txs_cache_miss++;
+
+			wlan_peer_flush_tx_rate_stats(soc_stats_ctx, stats_ctx);
+			__tx_stats = &tx_stats->stats[0];
+			__wlan_peer_update_tx_rate_stats(__tx_stats,
+							 ppdu_user);
+			tx_stats->cur_rix = ppdu_user->rix;
+			tx_stats->cur_cache_idx = 0;
+		}
+		RATE_STATS_LOCK_RELEASE(&tx_stats->lock);
+	}
+}
+
+static void
+wlan_peer_update_sojourn_stats(void *ctx,
+			       struct cdp_tx_sojourn_stats *sojourn_stats)
+{
+	struct wlan_peer_rate_stats_ctx *stats_ctx;
+	struct wlan_peer_tx_rate_stats *tx_stats;
+	uint8_t tid;
+
+	stats_ctx = (struct wlan_peer_rate_stats_ctx *)sojourn_stats->cookie;
+
+	if (qdf_unlikely(!stats_ctx)) {
+		qdf_warn("peer rate stats ctx is NULL, return");
+		return;
+	}
+
+	tx_stats = &stats_ctx->tx;
+
+	RATE_STATS_LOCK_ACQUIRE(&tx_stats->lock);
+	for (tid = 0; tid < CDP_DATA_TID_MAX; tid++) {
+		tx_stats->sojourn.avg_sojourn_msdu[tid] =
+			sojourn_stats->avg_sojourn_msdu[tid];
+
+		tx_stats->sojourn.sum_sojourn_msdu[tid] +=
+			sojourn_stats->sum_sojourn_msdu[tid];
+
+		tx_stats->sojourn.num_msdus[tid] +=
+			sojourn_stats->num_msdus[tid];
+	}
+	RATE_STATS_LOCK_RELEASE(&tx_stats->lock);
+}
+
+void wlan_peer_update_rate_stats(void *ctx,
+				 enum WDI_EVENT event,
+				 void *buf, uint16_t peer_id,
+				 uint32_t stats_type)
+{
+	struct wlan_soc_rate_stats_ctx *soc_stats_ctx;
+	struct cdp_tx_completion_ppdu *cdp_tx_ppdu;
+	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
+	struct cdp_tx_sojourn_stats *sojourn_stats;
+	qdf_nbuf_t nbuf;
+
+	if (qdf_unlikely(!buf))
+		return;
+
+	if (qdf_unlikely(!ctx))
+		return;
+
+	soc_stats_ctx = ctx;
+	nbuf = buf;
+
+	switch (event) {
+	case WDI_EVENT_TX_PPDU_DESC:
+		cdp_tx_ppdu = (struct cdp_tx_completion_ppdu *)
+					qdf_nbuf_data(nbuf);
+		wlan_peer_update_tx_rate_stats(soc_stats_ctx, cdp_tx_ppdu);
+		break;
+	case WDI_EVENT_RX_PPDU_DESC:
+		cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)
+					qdf_nbuf_data(nbuf);
+		wlan_peer_update_rx_rate_stats(soc_stats_ctx, cdp_rx_ppdu);
+		break;
+	case WDI_EVENT_TX_SOJOURN_STAT:
+		sojourn_stats = (struct cdp_tx_sojourn_stats *)
+					qdf_nbuf_data(nbuf);
+		wlan_peer_update_sojourn_stats(soc_stats_ctx, sojourn_stats);
+		break;
+	default:
+		qdf_err("Err, Invalid type");
+	}
+}
+
+void wlan_peer_create_event_handler(void *pdev, enum WDI_EVENT event,
+				    void *buf, uint16_t peer_id,
+				    uint32_t type)
+{
+	struct cdp_peer_cookie *peer_info;
+	struct wlan_peer_rate_stats_ctx *stats;
+
+	peer_info = (struct cdp_peer_cookie *)buf;
+	stats = qdf_mem_malloc(sizeof(*stats));
+	if (!stats) {
+		qdf_err("malloc failed, returning NULL");
+		return;
+	}
+	qdf_mem_zero(stats, sizeof(*stats));
+	RATE_STATS_LOCK_CREATE(&stats->tx.lock);
+	RATE_STATS_LOCK_CREATE(&stats->rx.lock);
+	qdf_mem_copy(stats->mac_addr, peer_info->mac_addr, QDF_MAC_ADDR_SIZE);
+	stats->peer_cookie = peer_info->cookie;
+	stats->pdev = pdev;
+
+	peer_info->ctx = (void *)stats;
+}
+
+void wlan_peer_destroy_event_handler(void *ctx, enum WDI_EVENT event,
+				     void *buf, uint16_t peer_id,
+				     uint32_t type)
+{
+	struct cdp_peer_cookie *peer_info;
+	struct wlan_peer_rate_stats_ctx *stats;
+
+	peer_info = (struct cdp_peer_cookie *)buf;
+	stats = (struct wlan_peer_rate_stats_ctx *)peer_info->ctx;
+
+	if (stats) {
+		wlan_peer_flush_rate_stats(ctx, stats);
+		RATE_STATS_LOCK_DESTROY(&stats->tx.lock);
+		RATE_STATS_LOCK_DESTROY(&stats->rx.lock);
+		qdf_mem_free(stats);
+		qdf_info("DEBUG DEiniitialized rate stats");
+	}
+}
+#endif
diff --git a/qal/inc/qal_notifier.h b/qal/inc/qal_notifier.h
new file mode 100644
index 0000000..0a538a3
--- /dev/null
+++ b/qal/inc/qal_notifier.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: qal_notifier (QAL notifier)
+ * QCA driver framework for OS notifier handlers
+ */
+
+#ifndef __QAL_NOTIFIER_H
+#define __QAL_NOTIFIER_H
+
+#include "qdf_types.h"
+
+typedef QDF_STATUS (*qal_panic_notifier)(void *data);
+
+/**
+ *
+ * qal_register_panic_notifier() - register to panic notifier chain
+ *
+ * To be called once, globally.
+ *
+ * Return: None
+ */
+QDF_STATUS qal_register_panic_notifier(qal_panic_notifier cb);
+
+/**
+ * qal_unregister_panic_notifier() - unregister linux panic notifier chain
+ *
+ * To be called once, globally.
+ *
+ * Return: None
+ */
+QDF_STATUS qal_unregister_panic_notifier(void);
+
+#endif /* __QAL_NOTIFIER_H */
diff --git a/qal/linux/src/qal_devcfg.c b/qal/linux/src/qal_devcfg.c
new file mode 100644
index 0000000..cf9aec4
--- /dev/null
+++ b/qal/linux/src/qal_devcfg.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: qal_devcfg
+ * This file provides OS dependent device config related APIs
+ */
+
+#include "qdf_debugfs.h"
+#include "qdf_mem.h"
+#include "qdf_types.h"
+#include "qdf_nbuf.h"
+#include "qdf_module.h"
+#include "qal_devcfg.h"
+#include <net/cfg80211.h>
+
+QDF_STATUS
+qal_devcfg_send_response(qdf_nbuf_t cfgbuf)
+{
+	int ret;
+
+	if (!cfgbuf)
+		return QDF_STATUS_E_INVAL;
+
+	ret = cfg80211_vendor_cmd_reply(cfgbuf);
+
+	return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_devcfg_send_response);
diff --git a/qal/linux/src/qal_notifier.c b/qal/linux/src/qal_notifier.c
new file mode 100644
index 0000000..c0a6746
--- /dev/null
+++ b/qal/linux/src/qal_notifier.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "qal_notifier.h"
+#include "qdf_module.h"
+#include "qdf_trace.h"
+
+static struct notifier_block qal_panic_nb;
+
+static qal_panic_notifier qal_panic_cb;
+
+static int qal_panic_notifier_handler(struct notifier_block *nb,
+				      unsigned long action, void *data)
+{
+	qal_panic_cb(data);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS qal_register_panic_notifier(qal_panic_notifier cb)
+{
+	QDF_ASSERT(!qal_panic_cb);
+	if (qal_panic_cb) {
+		qdf_err("Panic notifier already registered");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qal_panic_cb = cb;
+
+	qal_panic_nb.notifier_call = qal_panic_notifier_handler;
+	atomic_notifier_chain_register(&panic_notifier_list,
+				       &qal_panic_nb);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_register_panic_notifier);
+
+QDF_STATUS qal_unregister_panic_notifier(void)
+{
+	atomic_notifier_chain_unregister(&panic_notifier_list,
+					 &qal_panic_nb);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_unregister_panic_notifier);
diff --git a/qal/linux/src/qal_vbus_dev.c b/qal/linux/src/qal_vbus_dev.c
new file mode 100644
index 0000000..4b56b25
--- /dev/null
+++ b/qal/linux/src/qal_vbus_dev.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: qal_vbus_dev
+ * This file provides OS dependent virtual bus device related APIs
+ */
+
+#include "qdf_util.h"
+#include "qal_vbus_dev.h"
+#include "qdf_module.h"
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+#include <linux/reset.h>
+#endif
+
+QDF_STATUS
+qal_vbus_get_iorsc(int devnum, uint32_t flag, char *devname)
+{
+	int ret;
+
+	if (!devname)
+		return QDF_STATUS_E_INVAL;
+
+	ret = gpio_request_one(devnum, flag, devname);
+
+	return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_vbus_get_iorsc);
+
+QDF_STATUS
+qal_vbus_release_iorsc(int devnum)
+{
+	if (devnum <= 0)
+		return QDF_STATUS_E_INVAL;
+
+	gpio_free(devnum);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_vbus_release_iorsc);
+
+QDF_STATUS
+qal_vbus_enable_devclk(struct qdf_dev_clk *clk)
+{
+	int ret;
+
+	if (!clk)
+		return QDF_STATUS_E_INVAL;
+
+	ret = clk_prepare_enable((struct clk *)clk);
+
+	return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_vbus_enable_devclk);
+
+QDF_STATUS
+qal_vbus_disable_devclk(struct qdf_dev_clk *clk)
+{
+	if (!clk)
+		return QDF_STATUS_E_INVAL;
+
+	clk_disable_unprepare((struct clk *)clk);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_vbus_disable_devclk);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
+QDF_STATUS
+qal_vbus_get_dev_rstctl(struct qdf_pfm_hndl *pfhndl, const char *state,
+			struct qdf_vbus_rstctl **rstctl)
+{
+	struct reset_control *rsctl;
+
+	if (!pfhndl || !state)
+		return QDF_STATUS_E_INVAL;
+
+	rsctl = reset_control_get_optional_exclusive((struct device *)pfhndl,
+						     state);
+
+	if (!rsctl)
+		return QDF_STATUS_E_FAILURE;
+
+	*rstctl = (struct qdf_vbus_rstctl *)rsctl;
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+QDF_STATUS
+qal_vbus_get_dev_rstctl(struct qdf_pfm_hndl *pfhndl, const char *state,
+			struct qdf_vbus_rstctl **rstctl)
+{
+	struct reset_control *rsctl;
+
+	if (!pfhndl || !state)
+		return QDF_STATUS_E_INVAL;
+
+	rsctl = reset_control_get_optional((struct device *)pfhndl,
+					   state);
+
+	if (!rsctl)
+		return QDF_STATUS_E_FAILURE;
+
+	*rstctl = (struct qdf_vbus_rstctl *)rsctl;
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#else
+QDF_STATUS
+qal_vbus_get_dev_rstctl(struct qdf_pfm_hndl *pfhndl, const char *state,
+			struct qdf_vbus_rstctl **rstctl)
+{
+	if (!pfhndl || !state)
+		return QDF_STATUS_E_INVAL;
+	*rstctl = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+qdf_export_symbol(qal_vbus_get_dev_rstctl);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+QDF_STATUS
+qal_vbus_release_dev_rstctl(struct qdf_pfm_hndl *pfhndl,
+			    struct qdf_vbus_rstctl *rstctl)
+{
+	if (!pfhndl || !rstctl)
+		return QDF_STATUS_E_INVAL;
+
+	reset_control_put((struct reset_control *)rstctl);
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+QDF_STATUS
+qal_release_dev_rstctl(struct qdf_pfm_hndl *pfhndl,
+		       struct qdf_vbus_rstctl *rstctl)
+{
+	if (!pfhndl || !rstctl)
+		return QDF_STATUS_E_INVAL;
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif
+
+qdf_export_symbol(qal_vbus_release_dev_rstctl);
+
+QDF_STATUS
+qal_vbus_activate_dev_rstctl(struct qdf_pfm_hndl *pfhndl,
+			     struct qdf_vbus_rstctl *rstctl)
+{
+	int ret;
+
+	if (!pfhndl || !rstctl)
+		return QDF_STATUS_E_INVAL;
+
+	ret = reset_control_assert((struct reset_control *)rstctl);
+
+	return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_vbus_activate_dev_rstctl);
+
+QDF_STATUS
+qal_vbus_deactivate_dev_rstctl(struct qdf_pfm_hndl *pfhndl,
+			       struct qdf_vbus_rstctl *rstctl)
+{
+	int ret;
+
+	if (!pfhndl || !rstctl)
+		return QDF_STATUS_E_INVAL;
+
+	ret = reset_control_deassert((struct reset_control *)rstctl);
+
+	return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_vbus_deactivate_dev_rstctl);
+
+QDF_STATUS
+qal_vbus_get_resource(struct qdf_pfm_hndl *pfhndl,
+		      struct qdf_vbus_resource **rsc,
+		      uint32_t restype, uint32_t residx)
+{
+	struct resource *rsrc;
+
+	if (!pfhndl)
+		return QDF_STATUS_E_INVAL;
+
+	rsrc = platform_get_resource((struct platform_device *)pfhndl,
+				     restype, residx);
+	if (!rsrc)
+		return QDF_STATUS_E_FAILURE;
+
+	*rsc = (struct qdf_vbus_resource *)rsrc;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_vbus_get_resource);
+
+QDF_STATUS
+qal_vbus_get_irq(struct qdf_pfm_hndl *pfhndl, const char *str, int *irq)
+{
+	int inum;
+
+	if (!pfhndl || !str)
+		return QDF_STATUS_E_INVAL;
+
+	inum = platform_get_irq_byname((struct platform_device *)pfhndl, str);
+
+	if (inum < 0)
+		return QDF_STATUS_E_FAULT;
+
+	*irq = inum;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_vbus_get_irq);
+
+QDF_STATUS
+qal_vbus_register_driver(struct qdf_pfm_drv *pfdev)
+{
+	int ret;
+
+	if (!pfdev)
+		return QDF_STATUS_E_INVAL;
+
+	ret = platform_driver_register((struct platform_driver *)pfdev);
+
+	return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_vbus_register_driver);
+
+QDF_STATUS
+qal_vbus_deregister_driver(struct qdf_pfm_drv *pfdev)
+{
+	if (!pfdev)
+		return QDF_STATUS_E_INVAL;
+
+	platform_driver_unregister((struct platform_driver *)pfdev);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_vbus_deregister_driver);
diff --git a/target_if/cfr/src/target_if_cfr_8074v2.c b/target_if/cfr/src/target_if_cfr_8074v2.c
index 90c145b..f0eb26c 100644
--- a/target_if/cfr/src/target_if_cfr_8074v2.c
+++ b/target_if/cfr/src/target_if_cfr_8074v2.c
@@ -426,7 +426,8 @@
 	header->chip_type              = CFR_CAPTURE_RADIO_HKV2;
 	header->pltform_type           = CFR_PLATFORM_TYPE_ARM;
 	header->Reserved               = 0;
-	header->u.meta_v1.status       = tx_evt_param.status;
+	header->u.meta_v1.status       = (tx_evt_param.status &
+					  PEER_CFR_CAPTURE_EVT_STATUS_MASK)?0:1;
 	header->u.meta_v1.channel_bw   = tx_evt_param.bandwidth;
 	header->u.meta_v1.phy_mode     = tx_evt_param.phy_mode;
 	header->u.meta_v1.prim20_chan  = tx_evt_param.primary_20mhz_chan;
diff --git a/tools/linux/peerstats.c b/tools/linux/peerstats.c
new file mode 100644
index 0000000..adb2bcb
--- /dev/null
+++ b/tools/linux/peerstats.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * file: peer rate statitistics application
+ * This file provides framework to display peer rate statistics
+ */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <qcatools_lib.h>
+#include <dp_rate_stats_pub.h>
+
+#ifndef min
+#define min(x, y) ((x) < (y) ? (x) : (y))
+#else
+#error confilicting defs of min
+#endif
+
+#define DP_PEER_STATS_PRINT(fmt, ...) \
+	do { \
+		printf(fmt, ##__VA_ARGS__); \
+		printf("\n"); \
+	} while (0)
+
+char interface[IFNAMSIZ];
+
+static void dp_peer_rx_rate_stats_print(uint8_t *peer_mac,
+					uint64_t peer_cookie,
+					void *buffer,
+					uint32_t buffer_len)
+{
+	int i = 0;
+	struct wlan_rx_rate_stats *rx_stats;
+
+	rx_stats = (struct wlan_rx_rate_stats *)buffer;
+	DP_PEER_STATS_PRINT("\n......................................");
+	DP_PEER_STATS_PRINT("......................................");
+	DP_PEER_STATS_PRINT("PEER %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
+			    peer_mac[0],
+			    peer_mac[1],
+			    peer_mac[2],
+			    peer_mac[3],
+			    peer_mac[4],
+			    peer_mac[5]);
+	DP_PEER_STATS_PRINT("\tpeer cookie: %016llx\n",
+			    peer_cookie);
+	DP_PEER_STATS_PRINT("\n..............................................");
+	DP_PEER_STATS_PRINT("................................");
+	DP_PEER_STATS_PRINT("................................................");
+	DP_PEER_STATS_PRINT(".................................\n");
+	DP_PEER_STATS_PRINT("\tRx statistics:");
+	DP_PEER_STATS_PRINT(" %10s | %10s | %10s | %10s | %10s | %10s",
+			    "rate",
+			    "rix",
+			    "bytes",
+			    "msdus",
+			    "mpdus",
+			    "ppdus");
+	DP_PEER_STATS_PRINT("\t\t%10s | %10s | %10s | %10s | %10s | %10s |",
+			    "retries",
+			    "rssi",
+			    "rssi 1 p20",
+			    "rssi 1 e20",
+			    "rssi 1 e40",
+			    "rssi 1 e80");
+	DP_PEER_STATS_PRINT(" | %10s | | %10s | %10s | %10s | %10s | %10s",
+			    "rssi 2 p20",
+			    "rssi 2 e20",
+			    "rssi 2 e40",
+			    "rssi 2 e80",
+			    "rssi 3 p20",
+			    "rssi 3 e20");
+	DP_PEER_STATS_PRINT(" | %10s | %10s | %10s | %10s | %10s | %10s\n\n\n",
+			    "rssi 3 e40",
+			    "rssi 3 e80",
+			    "rssi 4 p20",
+			    "rssi 4 e20",
+			    "rssi 4 e40",
+			    "rssi 4 e80");
+
+	for (i = 0; i < WLANSTATS_CACHE_SIZE; i++) {
+		DP_PEER_STATS_PRINT("\t\t%10u | %10u | %10u | %10u | %10u |",
+				    rx_stats->rate,
+				    rx_stats->rix,
+				    rx_stats->num_bytes,
+				    rx_stats->num_msdus,
+				    rx_stats->num_mpdus
+				     );
+		DP_PEER_STATS_PRINT(" %10u | %10u | %10u | %10u | %10u |",
+				    rx_stats->num_ppdus,
+				    rx_stats->num_retries,
+				    rx_stats->num_sgi,
+				    rx_stats->avg_rssi,
+				    rx_stats->avg_rssi_ant[0][0]);
+		DP_PEER_STATS_PRINT(" %10u | %10u | %10u | %10u | %10u |",
+				    rx_stats->avg_rssi_ant[0][1],
+				    rx_stats->avg_rssi_ant[0][2],
+				    rx_stats->avg_rssi_ant[0][3],
+				    rx_stats->avg_rssi_ant[1][0],
+				    rx_stats->avg_rssi_ant[1][1]);
+		DP_PEER_STATS_PRINT(" %10u | %10u | %10u | %10u | %10u |",
+				    rx_stats->avg_rssi_ant[1][2],
+				    rx_stats->avg_rssi_ant[1][3],
+				    rx_stats->avg_rssi_ant[2][0],
+				    rx_stats->avg_rssi_ant[2][1],
+				    rx_stats->avg_rssi_ant[2][2]);
+		DP_PEER_STATS_PRINT(" %10u | %10u | %10u | %10u | %10u\n\n\n",
+				    rx_stats->avg_rssi_ant[2][3],
+				    rx_stats->avg_rssi_ant[3][0],
+				    rx_stats->avg_rssi_ant[3][1],
+				    rx_stats->avg_rssi_ant[3][2],
+				    rx_stats->avg_rssi_ant[3][3]);
+		rx_stats = rx_stats + 1;
+	}
+}
+
+static void
+dp_peer_tx_sojourn_stats_print(uint8_t *peer_mac,
+			       uint64_t peer_cookie,
+			       struct wlan_tx_sojourn_stats *sojourn_stats)
+{
+	uint8_t tid;
+
+	DP_PEER_STATS_PRINT("\n..........................................");
+	DP_PEER_STATS_PRINT("....................................");
+	DP_PEER_STATS_PRINT("....................................");
+	DP_PEER_STATS_PRINT(".........................................\n");
+	DP_PEER_STATS_PRINT("PEER%02hhx:%02hhx:%02hhx:%02hhx%02hhx:%02hhx\n",
+			    peer_mac[0],
+			    peer_mac[1],
+			    peer_mac[2],
+			    peer_mac[3],
+			    peer_mac[4],
+			    peer_mac[5]);
+	DP_PEER_STATS_PRINT("\tPEER Cookie: %016llx\n",
+			    peer_cookie);
+	DP_PEER_STATS_PRINT("\n...........................................");
+	DP_PEER_STATS_PRINT("...................................");
+	DP_PEER_STATS_PRINT("..................................");
+	DP_PEER_STATS_PRINT("............................................");
+	DP_PEER_STATS_PRINT("\n\tSojourn statistics:\n");
+	DP_PEER_STATS_PRINT("\t\t%10s %10s %20s %20s\n",
+			    "tid",
+			    "ave",
+			    "sum",
+			    "num");
+
+	for (tid = 0; tid < WLAN_DATA_TID_MAX; tid++) {
+				/* change sum_sojourn_msdu data type to u64 */
+		DP_PEER_STATS_PRINT("\t\t%10d %10u %20u %20u\n",
+				    tid,
+				    sojourn_stats->avg_sojourn_msdu[tid],
+				    sojourn_stats->sum_sojourn_msdu[tid],
+				    sojourn_stats->num_msdus[tid]);
+	}
+	DP_PEER_STATS_PRINT("\n...........................................");
+	DP_PEER_STATS_PRINT("...................................");
+	DP_PEER_STATS_PRINT("...................................");
+	DP_PEER_STATS_PRINT("...........................................\n");
+}
+
+static void dp_peer_tx_rate_stats_print(uint8_t *peer_mac,
+					uint64_t peer_cookie,
+					void *buffer,
+					uint32_t buffer_len)
+{
+	int i = 0;
+	struct wlan_tx_rate_stats *tx_stats;
+	struct wlan_tx_sojourn_stats *sojourn_stats;
+
+	if (buffer_len < (WLANSTATS_CACHE_SIZE *
+			  sizeof(struct wlan_tx_rate_stats))
+			  + sizeof(struct wlan_tx_sojourn_stats)) {
+		DP_PEER_STATS_PRINT("invalid buffer len, return");
+		return;
+	}
+	tx_stats = (struct wlan_tx_rate_stats *)buffer;
+	DP_PEER_STATS_PRINT("\n...........................................");
+	DP_PEER_STATS_PRINT("...................................");
+	DP_PEER_STATS_PRINT("...................................");
+	DP_PEER_STATS_PRINT("...........................................\n");
+	DP_PEER_STATS_PRINT("PEER%02hhx:%02hhx:%02hhx:%02hhx%02hhx:%02hhx\n\n",
+			    peer_mac[0],
+			    peer_mac[1],
+			    peer_mac[2],
+			    peer_mac[3],
+			    peer_mac[4],
+			    peer_mac[5]);
+	DP_PEER_STATS_PRINT("\tPEER Cookie: %016llx",
+			    peer_cookie);
+	DP_PEER_STATS_PRINT("\n...........................................");
+	DP_PEER_STATS_PRINT("...................................");
+	DP_PEER_STATS_PRINT("...................................");
+	DP_PEER_STATS_PRINT("...........................................\n");
+	DP_PEER_STATS_PRINT("\tTx statistics:\n");
+	DP_PEER_STATS_PRINT("\t\t%10s | %10s | %10s | %10s | %10s",
+			    "rate",
+			    "rix",
+			    "attempts",
+			    "success",
+			    "ppdus");
+	for (i = 0; i < WLANSTATS_CACHE_SIZE; i++) {
+		DP_PEER_STATS_PRINT("\t\t%10u | %10u | %10u | %10u | %10u\n",
+				    tx_stats->rate,
+				    tx_stats->rix,
+				    tx_stats->mpdu_attempts,
+				    tx_stats->mpdu_success,
+				    tx_stats->num_ppdus);
+		tx_stats = tx_stats + 1;
+	}
+
+	sojourn_stats = buffer + (WLANSTATS_CACHE_SIZE *
+				  sizeof(struct wlan_tx_rate_stats));
+	dp_peer_tx_sojourn_stats_print(peer_mac, peer_cookie, sojourn_stats);
+
+	return;
+}
+
+static void dp_peer_stats_handler(uint32_t cache_type,
+				 uint8_t *peer_mac,
+				 uint64_t peer_cookie,
+				 void *buffer,
+				 uint32_t buffer_len)
+{
+	switch (cache_type) {
+	case DP_PEER_RX_RATE_STATS:
+		dp_peer_rx_rate_stats_print(peer_mac, peer_cookie,
+					    buffer, buffer_len);
+		break;
+	case DP_PEER_TX_RATE_STATS:
+		dp_peer_tx_rate_stats_print(peer_mac, peer_cookie,
+					    buffer, buffer_len);
+		break;
+	}
+}
+
+static void
+dp_peer_stats_event_callback(char *ifname,
+			     uint32_t cmdid,
+			     uint8_t *data,
+			     size_t len)
+{
+	struct nlattr *tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_MAX + 1];
+	struct nlattr *tb;
+	void *buffer = NULL;
+	uint32_t buffer_len = 0;
+	uint8_t *peer_mac;
+	uint32_t cache_type;
+	uint64_t peer_cookie;
+
+	if (cmdid != QCA_NL80211_VENDOR_SUBCMD_PEER_STATS_CACHE_FLUSH) {
+		/* ignore anyother events*/
+		return;
+	}
+
+	if (strncmp(interface, ifname, sizeof(interface)) != 0) {
+		/* ignore events for other interfaces*/
+		return;
+	}
+
+	if (nla_parse(tb_array, QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_MAX,
+		      (struct nlattr *)data, len, NULL)) {
+		printf("INVALID EVENT\n");
+		return;
+	}
+
+	tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE];
+	if (!tb) {
+		printf("#############%s:%d\n", __func__, __LINE__);
+		return;
+	}
+	cache_type = nla_get_u32(tb);
+
+	tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_MAC];
+	if (!tb) {
+		printf("#############%s:%d\n", __func__, __LINE__);
+		return;
+	}
+	peer_mac = (uint8_t *)nla_data(tb);
+
+	tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_DATA];
+	if (tb) {
+		buffer = (void *)nla_data(tb);
+		buffer_len = nla_len(tb);
+	}
+
+	tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_COOKIE];
+	if (!tb) {
+		printf("#############%s:%d\n", __func__, __LINE__);
+		return;
+	}
+	peer_cookie = nla_get_u64(tb);
+	if (!buffer) {
+		printf("#############%s:%d\n", __func__, __LINE__);
+		return;
+	}
+
+	dp_peer_stats_handler(cache_type, peer_mac, peer_cookie,
+			      buffer, buffer_len);
+}
+
+int main(int argc, char *argv[])
+{
+	int err = 0;
+	wifi_cfg80211_context cfg80211_ctxt;
+	char *ifname;
+	int num_msecs = 0;
+	int status = 0;
+
+	if (argc < 2) {
+		fprintf(stderr, "Invalid commands args\n");
+		return -EIO;
+	}
+
+	/* Reset the cfg80211 context to 0 if the application does not pass
+	 * custom private event and command sockets. In this case, the default
+	 * port is used for netlink communication.
+	 */
+	memset(&cfg80211_ctxt, 0, sizeof(wifi_cfg80211_context));
+
+	ifname = argv[1];
+	memcpy(interface, ifname, sizeof(interface));
+	cfg80211_ctxt.event_callback = dp_peer_stats_event_callback;
+
+	err = wifi_init_nl80211(&cfg80211_ctxt);
+	if (err) {
+		fprintf(stderr, "unable to create NL socket\n");
+		return -EIO;
+	}
+
+	/* Starting event thread to listen for responses*/
+	if (wifi_nl80211_start_event_thread(&cfg80211_ctxt)) {
+		fprintf(stderr, "Unable to setup nl80211 event thread\n");
+		status = -EIO;
+		goto cleanup;
+	}
+
+	while (true) {
+		/*sleep for 1 ms*/
+		usleep(1000);
+		num_msecs++;
+	}
+
+	wifi_destroy_nl80211(&cfg80211_ctxt);
+	return 0;
+
+cleanup:
+	wifi_destroy_nl80211(&cfg80211_ctxt);
+	return status;
+}
diff --git a/umac/dfs/core/src/misc/dfs_zero_cac.c b/umac/dfs/core/src/misc/dfs_zero_cac.c
index 9488f9e..25442b6 100644
--- a/umac/dfs/core/src/misc/dfs_zero_cac.c
+++ b/umac/dfs/core/src/misc/dfs_zero_cac.c
@@ -95,6 +95,8 @@
 #include "wlan_dfs_utils_api.h"
 #include "dfs_internal.h"
 #include "dfs_etsi_precac.h"
+#include "target_if.h"
+#include "wlan_dfs_init_deinit_api.h"
 
 void dfs_zero_cac_reset(struct wlan_dfs *dfs)
 {
@@ -102,7 +104,6 @@
 
 	dfs_get_override_precac_timeout(dfs,
 			&(dfs->dfs_precac_timeout_override));
-	qdf_timer_sync_cancel(&dfs->dfs_precac_timer);
 	dfs->dfs_precac_primary_freq = 0;
 	dfs->dfs_precac_secondary_freq = 0;
 
@@ -120,9 +121,9 @@
 	PRECAC_LIST_UNLOCK(dfs);
 }
 
-void dfs_zero_cac_timer_detach(struct wlan_dfs *dfs)
+void dfs_zero_cac_timer_detach(struct dfs_soc_priv_obj *dfs_soc_obj)
 {
-	qdf_timer_free(&dfs->dfs_precac_timer);
+	qdf_timer_free(&dfs_soc_obj->dfs_precac_timer);
 }
 
 int dfs_override_precac_timeout(struct wlan_dfs *dfs, int precac_timeout)
@@ -265,30 +266,115 @@
 	return ret_val;
 }
 
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_find_pdev_for_agile_precac(struct wlan_objmgr_pdev *pdev,
+				    uint8_t *cur_precac_dfs_index)
+{
+	struct wlan_dfs *dfs;
+	struct dfs_soc_priv_obj *dfs_soc_obj;
+	struct wlan_objmgr_psoc *psoc;
+
+	dfs = wlan_pdev_get_dfs_obj(pdev);
+	psoc = wlan_pdev_get_psoc(pdev);
+
+	dfs_soc_obj = dfs->dfs_soc_obj;
+
+	*cur_precac_dfs_index =
+	   (dfs_soc_obj->cur_precac_dfs_index + 1) % dfs_soc_obj->num_dfs_privs;
+}
+
+void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_dfs *temp_dfs;
+	struct dfs_soc_priv_obj *dfs_soc_obj;
+	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
+	uint8_t ch_freq = 0;
+	uint8_t cur_dfs_idx = 0;
+	int i;
+
+	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+	dfs_soc_obj = dfs->dfs_soc_obj;
+
+	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
+
+	pdev = dfs->dfs_pdev_obj;
+
+	for (i = 0; i < dfs_soc_obj->num_dfs_privs; i++) {
+		dfs_find_pdev_for_agile_precac(pdev, &cur_dfs_idx);
+		dfs_soc_obj->cur_precac_dfs_index = cur_dfs_idx;
+		temp_dfs = dfs_soc_obj->dfs_priv[cur_dfs_idx].dfs;
+		pdev = temp_dfs->dfs_pdev_obj;
+		if (!dfs_soc_obj->dfs_priv[cur_dfs_idx].agile_precac_active)
+			continue;
+
+		dfs_find_vht80_chan_for_agile_precac(temp_dfs,
+						     &ch_freq,
+			temp_dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1,
+			temp_dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2);
+
+		if (!ch_freq) {
+			qdf_info(" %s : %d No preCAC required channels left in current pdev: %pK",
+				 __func__, __LINE__, pdev);
+			continue;
+		} else {
+			break;
+		}
+	}
+
+	if (ch_freq) {
+		qdf_info("%s : %d ADFS channel set request sent for pdev: %pK ch_freq: %d",
+			 __func__, __LINE__, pdev, ch_freq);
+		if (dfs_tx_ops && dfs_tx_ops->dfs_agile_ch_cfg_cmd)
+			dfs_tx_ops->dfs_agile_ch_cfg_cmd(pdev, &ch_freq);
+		else
+			dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
+				"dfs_tx_ops=%pK", dfs_tx_ops);
+	} else {
+		qdf_info("No channels in preCAC required list");
+	}
+}
+#endif
+
 #define VHT80_IEEE_FREQ_OFFSET 6
 
 void dfs_mark_precac_dfs(struct wlan_dfs *dfs,
-		uint8_t is_radar_found_on_secondary_seg)
+		uint8_t is_radar_found_on_secondary_seg, uint8_t detector_id)
 {
 	struct dfs_precac_entry *precac_entry = NULL, *tmp_precac_entry = NULL;
 	uint8_t found = 0;
+	struct wlan_objmgr_psoc *psoc;
+	struct dfs_soc_priv_obj *dfs_soc_obj;
 
-	dfs_debug(dfs, WLAN_DEBUG_DFS,
-		"is_radar_found_on_secondary_seg = %u secondary_freq = %u primary_freq = %u",
-		is_radar_found_on_secondary_seg,
-		dfs->dfs_precac_secondary_freq,
-		dfs->dfs_precac_primary_freq);
+	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+	dfs_soc_obj = dfs->dfs_soc_obj;
 
-	/*
-	 * Even if radar found on primary, we need to move the channel from
-	 * precac-required-list and precac-done-list to precac-nol-list.
-	 */
-	PRECAC_LIST_LOCK(dfs);
-	if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
-		TAILQ_FOREACH_SAFE(precac_entry,
-				&dfs->dfs_precac_required_list,
-				pe_list,
-				tmp_precac_entry) {
+	if (is_radar_found_on_secondary_seg) {
+		dfs_debug(dfs, WLAN_DEBUG_DFS,
+			  "is_radar_found_on_secondary_seg = %u secondary_freq = %u primary_freq = %u",
+			  is_radar_found_on_secondary_seg,
+			  dfs->dfs_precac_secondary_freq,
+			  dfs->dfs_precac_primary_freq);
+	} else {
+		dfs->dfs_precac_secondary_freq = dfs->dfs_agile_precac_freq;
+		dfs_debug(dfs, WLAN_DEBUG_DFS,
+			  "agile_precac_freq = %u ",
+			  dfs->dfs_agile_precac_freq);
+	}
+
+	if (detector_id != AGILE_DETECTOR_ID) {
+		/*
+		 * Even if radar found on primary, we need to move
+		 * the channel from precac-required-list and precac-done-list
+		 * to precac-nol-list.
+		 */
+		PRECAC_LIST_LOCK(dfs);
+		if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
+			TAILQ_FOREACH_SAFE(precac_entry,
+					   &dfs->dfs_precac_required_list,
+					   pe_list,
+					   tmp_precac_entry) {
 			/*
 			 * If on primary then use IS_WITHIN_RANGE else use
 			 * equality directly.
@@ -300,52 +386,110 @@
 				     precac_entry->vht80_freq,
 				     VHT80_IEEE_FREQ_OFFSET)) {
 				TAILQ_REMOVE(&dfs->dfs_precac_required_list,
-						precac_entry, pe_list);
+					     precac_entry, pe_list);
 
 				dfs_debug(dfs, WLAN_DEBUG_DFS,
-					"removing the freq = %u from required list and adding to NOL list",
-					precac_entry->vht80_freq);
+					  "removing the freq = %u from required list and adding to NOL list",
+					  precac_entry->vht80_freq);
 				TAILQ_INSERT_TAIL(&dfs->dfs_precac_nol_list,
-						precac_entry, pe_list);
+						  precac_entry, pe_list);
 				qdf_timer_mod(&precac_entry->precac_nol_timer,
-						dfs_get_nol_timeout(dfs)*1000);
+					      dfs_get_nol_timeout(dfs) * 1000);
 				found = 1;
 				break;
+				}
 			}
 		}
-	}
 
-	/* If not found in precac-required-list remove from precac-done-list */
-	if (!found && !TAILQ_EMPTY(&dfs->dfs_precac_done_list)) {
-		TAILQ_FOREACH_SAFE(precac_entry,
-				&dfs->dfs_precac_done_list,
-				pe_list,
-				tmp_precac_entry) {
-			/*
-			 * If on primary then use IS_WITHIN_RANGE else use
-			 * equality directly.
-			 */
-			if (is_radar_found_on_secondary_seg ?
+		/*
+		 * If not found in precac-required-list
+		 * remove from precac-done-list
+		 */
+		if (!found && !TAILQ_EMPTY(&dfs->dfs_precac_done_list)) {
+			TAILQ_FOREACH_SAFE(precac_entry,
+					   &dfs->dfs_precac_done_list,
+					   pe_list,
+					   tmp_precac_entry) {
+				/*
+				 * If on primary then use IS_WITHIN_RANGE
+				 * else use equality directly.
+				 */
+				if (is_radar_found_on_secondary_seg ?
 					(dfs->dfs_precac_secondary_freq ==
 					 precac_entry->vht80_freq) :
 					IS_WITHIN_RANGE(
 						dfs->dfs_curchan->dfs_ch_ieee,
 						precac_entry->vht80_freq, 6)) {
-				TAILQ_REMOVE(&dfs->dfs_precac_done_list,
-					precac_entry, pe_list);
+					TAILQ_REMOVE(&dfs->dfs_precac_done_list,
+						     precac_entry, pe_list);
 
-				dfs_debug(dfs, WLAN_DEBUG_DFS,
-					"removing the the freq = %u from done list and adding to NOL list",
-					precac_entry->vht80_freq);
-				TAILQ_INSERT_TAIL(&dfs->dfs_precac_nol_list,
+					dfs_debug(dfs, WLAN_DEBUG_DFS,
+						  "removing the freq = %u from done list and adding to NOL list",
+						  precac_entry->vht80_freq);
+					TAILQ_INSERT_TAIL(
+						&dfs->dfs_precac_nol_list,
 						precac_entry, pe_list);
-				qdf_timer_mod(&precac_entry->precac_nol_timer,
-						dfs_get_nol_timeout(dfs)*1000);
-				break;
+					qdf_timer_mod(
+					&precac_entry->precac_nol_timer,
+					dfs_get_nol_timeout(dfs) * 1000);
+					break;
+				}
 			}
 		}
+		PRECAC_LIST_UNLOCK(dfs);
+	} else {
+		PRECAC_LIST_LOCK(dfs);
+		if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
+			TAILQ_FOREACH_SAFE(precac_entry,
+					   &dfs->dfs_precac_required_list,
+					   pe_list,
+					   tmp_precac_entry) {
+			if (dfs->dfs_precac_secondary_freq ==
+				 precac_entry->vht80_freq) {
+				TAILQ_REMOVE(&dfs->dfs_precac_required_list,
+					     precac_entry, pe_list);
+
+				dfs_debug(dfs, WLAN_DEBUG_DFS,
+					  "removing the freq = %u from required list and adding to NOL list",
+					  precac_entry->vht80_freq);
+				TAILQ_INSERT_TAIL(&dfs->dfs_precac_nol_list,
+						  precac_entry, pe_list);
+				qdf_timer_mod(&precac_entry->precac_nol_timer,
+					      dfs_get_nol_timeout(dfs) * 1000);
+				found = 1;
+				break;
+				}
+			}
+		}
+
+		/* If not found in precac-required-list
+		 * remove from precac-done-list
+		 */
+		if (!found && !TAILQ_EMPTY(&dfs->dfs_precac_done_list)) {
+			TAILQ_FOREACH_SAFE(precac_entry,
+					   &dfs->dfs_precac_done_list,
+					   pe_list,
+					   tmp_precac_entry) {
+				if (dfs->dfs_precac_secondary_freq ==
+					 precac_entry->vht80_freq) {
+					TAILQ_REMOVE(&dfs->dfs_precac_done_list,
+						     precac_entry, pe_list);
+
+					dfs_debug(dfs, WLAN_DEBUG_DFS,
+						  "removing the the freq = %u from done list and adding to NOL list",
+						  precac_entry->vht80_freq);
+					TAILQ_INSERT_TAIL(
+						&dfs->dfs_precac_nol_list,
+						precac_entry, pe_list);
+					qdf_timer_mod(
+					&precac_entry->precac_nol_timer,
+					dfs_get_nol_timeout(dfs) * 1000);
+					break;
+				}
+			}
+		}
+		PRECAC_LIST_UNLOCK(dfs);
 	}
-	PRECAC_LIST_UNLOCK(dfs);
 
 	/* TO BE DONE  xxx:- Need to lock the channel change */
 	/*
@@ -353,10 +497,10 @@
 	 * channel change will happen after RANDOM channel selection anyway.
 	 */
 
-	if (dfs->dfs_precac_timer_running) {
+	if (dfs_soc_obj->dfs_precac_timer_running) {
 		/* Cancel the PreCAC timer */
-		qdf_timer_stop(&dfs->dfs_precac_timer);
-		dfs->dfs_precac_timer_running = 0;
+		qdf_timer_stop(&dfs_soc_obj->dfs_precac_timer);
+		dfs_soc_obj->dfs_precac_timer_running = 0;
 
 		/*
 		 * Change the channel
@@ -368,19 +512,57 @@
 			if (dfs_is_ap_cac_timer_running(dfs)) {
 				dfs->dfs_defer_precac_channel_change = 1;
 				dfs_debug(dfs, WLAN_DEBUG_DFS,
-					"Primary CAC is running, defer the channel change"
-					);
+					  "Primary CAC is running, defer the channel change"
+					  );
 			} else {
 				dfs_mlme_channel_change_by_precac(
 						dfs->dfs_pdev_obj);
 			}
+		} else {
+			dfs_debug(dfs, WLAN_DEBUG_DFS,
+				  "PreCAC timer interrupted due to RADAR, Sending Agile channel set command"
+				  );
+			dfs_prepare_agile_precac_chan(dfs);
 		}
 	}
 }
 
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev,
+			       uint32_t ocac_status,
+			       uint32_t center_freq)
+{
+	struct wlan_dfs *dfs = NULL;
+
+	dfs = wlan_pdev_get_dfs_obj(pdev);
+
+	/* STOP TIMER irrespective of status */
+	utils_dfs_cancel_precac_timer(pdev);
+	if (ocac_status == OCAC_RESET) {
+		dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
+			  "PreCAC timer reset, Sending Agile chan set command");
+		dfs_prepare_agile_precac_chan(dfs);
+	} else if (ocac_status == OCAC_CANCEL) {
+		dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
+			  "PreCAC timer abort, agile precac stopped");
+	} else if (ocac_status == OCAC_SUCCESS) {
+		dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
+			  "PreCAC timer Completed for agile freq: %d",
+			  center_freq);
+		/*
+		 * TRIGGER agile precac timer with 0sec timeout
+		 * with ocac_status 0 for old pdev
+		 */
+		dfs_start_agile_precac_timer(dfs, center_freq, ocac_status);
+	} else {
+		dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, "Error Unknown");
+	}
+}
+#endif
+
 bool dfs_is_precac_timer_running(struct wlan_dfs *dfs)
 {
-	return dfs->dfs_precac_timer_running ? true : false;
+	return dfs->dfs_soc_obj->dfs_precac_timer_running ? true : false;
 }
 
 #define VHT80_IEEE_FREQ_OFFSET 6
@@ -498,59 +680,102 @@
 {
 	struct dfs_precac_entry *precac_entry, *tmp_precac_entry;
 	struct wlan_dfs *dfs = NULL;
+	struct dfs_soc_priv_obj *dfs_soc_obj = NULL;
+	uint32_t current_time;
 
-	OS_GET_TIMER_ARG(dfs, struct wlan_dfs *);
-	dfs->dfs_precac_timer_running = 0;
+	OS_GET_TIMER_ARG(dfs_soc_obj, struct dfs_soc_priv_obj *);
 
-	/*
-	 * Remove the HVT80 freq from the precac-required-list and add it to the
-	 * precac-done-list
-	 */
+	dfs = dfs_soc_obj->dfs_priv[dfs_soc_obj->cur_precac_dfs_index].dfs;
+	dfs_soc_obj->dfs_precac_timer_running = 0;
 
-	PRECAC_LIST_LOCK(dfs);
-	if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
-		TAILQ_FOREACH_SAFE(precac_entry,
-				&dfs->dfs_precac_required_list,
-				pe_list,
-				tmp_precac_entry) {
-			if (dfs->dfs_precac_secondary_freq ==
-					precac_entry->vht80_freq) {
+	if (!dfs->dfs_agile_precac_enable) {
+		/*
+		 * Remove the HT80 freq from the precac-required-list
+		 * and add it to the precac-done-list
+		 */
+
+		PRECAC_LIST_LOCK(dfs);
+		if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
+			TAILQ_FOREACH_SAFE(precac_entry,
+					   &dfs->dfs_precac_required_list,
+					   pe_list,
+					   tmp_precac_entry) {
+				if (dfs->dfs_precac_secondary_freq !=
+						precac_entry->vht80_freq)
+					continue;
+
 				TAILQ_REMOVE(&dfs->dfs_precac_required_list,
-						precac_entry, pe_list);
+					     precac_entry, pe_list);
 				dfs_debug(dfs, WLAN_DEBUG_DFS,
-					"removing the the freq = %u from required list and adding to done list",
-					precac_entry->vht80_freq);
+					  "removing the the freq = %u from required list and adding to done list",
+					  precac_entry->vht80_freq);
 				TAILQ_INSERT_TAIL(&dfs->dfs_precac_done_list,
-						precac_entry, pe_list);
+						  precac_entry, pe_list);
 				break;
 			}
 		}
-	}
-	PRECAC_LIST_UNLOCK(dfs);
+		PRECAC_LIST_UNLOCK(dfs);
 
-	dfs_debug(dfs, WLAN_DEBUG_DFS,
-		"Pre-cac expired, Precac Secondary chan %u curr time %d",
-		dfs->dfs_precac_secondary_freq,
-		(qdf_system_ticks_to_msecs(qdf_system_ticks()) / 1000));
-	/*
-	 * Do vdev restart so that we can change the secondary VHT80 channel.
-	 */
-	dfs_precac_check_home_chan_change(dfs);
+		current_time = qdf_system_ticks_to_msecs(qdf_system_ticks());
+		dfs_debug(dfs, WLAN_DEBUG_DFS,
+			  "Pre-cac expired, Precac Secondary chan %u curr time %d",
+			  dfs->dfs_precac_secondary_freq,
+			  (current_time) / 1000);
+		/*
+		 * Do vdev restart so that we can change
+		 * the secondary VHT80 channel.
+		 */
+		dfs_precac_check_home_chan_change(dfs);
+	} else {
+		current_time = qdf_system_ticks_to_msecs(qdf_system_ticks());
+		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+			 "Pre-cac expired, Agile Precac chan %u curr time %d",
+			 dfs->dfs_agile_precac_freq,
+			 current_time / 1000);
+		if (dfs_soc_obj->ocac_status == OCAC_SUCCESS) {
+			dfs_soc_obj->ocac_status = OCAC_RESET;
+			PRECAC_LIST_LOCK(dfs);
+				if (!TAILQ_EMPTY(
+					&dfs->dfs_precac_required_list)) {
+					TAILQ_FOREACH_SAFE(
+						precac_entry,
+						&dfs->dfs_precac_required_list,
+						pe_list,
+						tmp_precac_entry) {
+					if (dfs->dfs_agile_precac_freq !=
+						precac_entry->vht80_freq)
+						continue;
+
+					TAILQ_REMOVE(
+						&dfs->dfs_precac_required_list,
+						precac_entry, pe_list);
+					dfs_info(dfs, WLAN_DEBUG_DFS,
+						 "removing the freq = %u from required list and adding to done list",
+						 precac_entry->vht80_freq);
+					TAILQ_INSERT_TAIL(
+						&dfs->dfs_precac_done_list,
+						precac_entry, pe_list);
+					break;
+				}
+			}
+			PRECAC_LIST_UNLOCK(dfs);
+		}
+		dfs_prepare_agile_precac_chan(dfs);
+	}
 }
 
-void dfs_zero_cac_timer_init(struct wlan_dfs *dfs)
+void dfs_zero_cac_timer_init(struct dfs_soc_priv_obj *dfs_soc_obj)
 {
-	qdf_timer_init(NULL,
-			&(dfs->dfs_precac_timer),
-			dfs_precac_timeout,
-			(void *) dfs,
-			QDF_TIMER_TYPE_WAKE_APPS);
+	dfs_soc_obj->precac_state_started = false;
+	qdf_timer_init(NULL, &dfs_soc_obj->dfs_precac_timer,
+		       dfs_precac_timeout,
+		       (void *)dfs_soc_obj,
+		       QDF_TIMER_TYPE_WAKE_APPS);
 }
 
 void dfs_zero_cac_attach(struct wlan_dfs *dfs)
 {
 	dfs->dfs_precac_timeout_override = -1;
-	dfs_zero_cac_timer_init(dfs);
 	PRECAC_LIST_LOCK_CREATE(dfs);
 }
 
@@ -573,16 +798,24 @@
 		/* Move the channel from precac-NOL to precac-required-list */
 		TAILQ_REMOVE(&dfs->dfs_precac_nol_list, precac_entry, pe_list);
 		dfs_debug(dfs, WLAN_DEBUG_DFS,
-			"removing the the freq = %u from PreCAC NOL-list and adding Precac-required list",
-			 precac_entry->vht80_freq);
-		TAILQ_INSERT_TAIL(&dfs->dfs_precac_required_list, precac_entry,
-				pe_list);
+			  "removing the the freq = %u from PreCAC NOL-list and adding Precac-required list",
+			  precac_entry->vht80_freq);
+		TAILQ_INSERT_TAIL(&dfs->dfs_precac_required_list,
+				  precac_entry,
+				  pe_list);
 	}
 	PRECAC_LIST_UNLOCK(dfs);
 
-	/* TO BE DONE xxx : Need to lock the channel change */
-	/* Do a channel change */
-	dfs_mlme_channel_change_by_precac(dfs->dfs_pdev_obj);
+	if (!dfs->dfs_agile_precac_enable) {
+		/* TO BE DONE xxx : Need to lock the channel change */
+		/* Do a channel change */
+		dfs_mlme_channel_change_by_precac(dfs->dfs_pdev_obj);
+	} else {
+		dfs_debug(dfs, WLAN_DEBUG_DFS,
+			  "Precac NOL timeout, sending agile channel set command"
+			  );
+		dfs_prepare_agile_precac_chan(dfs);
+	}
 }
 
 void dfs_init_precac_list(struct wlan_dfs *dfs)
@@ -719,6 +952,26 @@
 
 }
 
+#if defined(QCA_SUPPORT_AGILE_DFS) || defined(ATH_SUPPORT_ZERO_CAC_DFS)
+void dfs_agile_soc_obj_init(struct wlan_dfs *dfs,
+			    struct wlan_objmgr_psoc *psoc)
+{
+	struct dfs_soc_priv_obj *dfs_soc_obj;
+
+	dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+							    WLAN_UMAC_COMP_DFS);
+	dfs->dfs_psoc_idx = dfs_soc_obj->num_dfs_privs;
+	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+		 "dfs->dfs_psoc_idx: %d ", dfs->dfs_psoc_idx);
+	dfs_soc_obj->dfs_priv[dfs_soc_obj->num_dfs_privs].dfs = dfs;
+	dfs_soc_obj->num_dfs_privs++;
+	dfs->dfs_soc_obj = dfs_soc_obj;
+
+	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_soc_obj->num_dfs_privs: %d ",
+		 dfs_soc_obj->num_dfs_privs);
+}
+#endif
+
 void dfs_zero_cac_detach(struct wlan_dfs *dfs)
 {
 	dfs_deinit_precac_list(dfs);
@@ -731,13 +984,15 @@
 	struct dfs_precac_entry *precac_entry;
 	uint8_t ieee_freq = 0;
 
-	dfs_debug(dfs, WLAN_DEBUG_DFS, "exclude_ieee_freq = %u",
+	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "exclude_ieee_freq = %u",
 		 exclude_ieee_freq);
 
 	PRECAC_LIST_LOCK(dfs);
 	if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
 		TAILQ_FOREACH(precac_entry, &dfs->dfs_precac_required_list,
 				pe_list) {
+			dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+				 "freq: %d ", precac_entry->vht80_freq);
 			if (precac_entry->vht80_freq != exclude_ieee_freq) {
 				ieee_freq = precac_entry->vht80_freq;
 				break;
@@ -745,27 +1000,75 @@
 		}
 	}
 	PRECAC_LIST_UNLOCK(dfs);
-	dfs_debug(dfs, WLAN_DEBUG_DFS, "ieee_freq = %u", ieee_freq);
+	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "ieee_freq = %u", ieee_freq);
 
 	return ieee_freq;
 }
 
 void dfs_cancel_precac_timer(struct wlan_dfs *dfs)
 {
-	qdf_timer_stop(&dfs->dfs_precac_timer);
-	dfs->dfs_precac_timer_running = 0;
+	struct dfs_soc_priv_obj *dfs_soc_obj;
+
+	dfs_soc_obj = dfs->dfs_soc_obj;
+	qdf_timer_stop(&dfs_soc_obj->dfs_precac_timer);
+	dfs_soc_obj->dfs_precac_timer_running = 0;
 }
 
-void dfs_start_precac_timer(struct wlan_dfs *dfs, uint8_t precac_chan)
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_start_agile_precac_timer(struct wlan_dfs *dfs, uint8_t precac_chan,
+				  uint8_t ocac_status)
+{
+	struct dfs_channel *ichan, lc;
+	uint8_t first_primary_dfs_ch_ieee;
+	int agile_cac_timeout;
+	struct dfs_soc_priv_obj *dfs_soc_obj;
+
+	dfs_soc_obj = dfs->dfs_soc_obj;
+	dfs_soc_obj->dfs_precac_timer_running = 1;
+
+	first_primary_dfs_ch_ieee = precac_chan - VHT80_IEEE_FREQ_OFFSET;
+	ichan = &lc;
+	dfs_mlme_find_dot11_channel(dfs->dfs_pdev_obj,
+				    first_primary_dfs_ch_ieee, 0,
+				    WLAN_PHYMODE_11AC_VHT80,
+				    &ichan->dfs_ch_freq,
+				    &ichan->dfs_ch_flags,
+				    &ichan->dfs_ch_flagext,
+				    &ichan->dfs_ch_ieee,
+				    &ichan->dfs_ch_vhtop_ch_freq_seg1,
+				    &ichan->dfs_ch_vhtop_ch_freq_seg2);
+	agile_cac_timeout = (dfs->dfs_precac_timeout_override != -1) ?
+				dfs->dfs_precac_timeout_override :
+	dfs_mlme_get_cac_timeout(dfs->dfs_pdev_obj,
+				 ichan->dfs_ch_freq,
+				 ichan->dfs_ch_vhtop_ch_freq_seg2,
+				 ichan->dfs_ch_flags);
+	if (ocac_status == OCAC_SUCCESS) {
+		dfs_soc_obj->ocac_status = OCAC_SUCCESS;
+		agile_cac_timeout = 0;
+	}
+
+	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+		 "precactimeout = %d", (agile_cac_timeout) * 1000);
+	qdf_timer_mod(&dfs_soc_obj->dfs_precac_timer,
+		      (agile_cac_timeout) * 1000);
+}
+#endif
+
+void dfs_start_precac_timer(struct wlan_dfs *dfs,
+			    uint8_t precac_chan)
 {
 	struct dfs_channel *ichan, lc;
 	uint8_t first_primary_dfs_ch_ieee;
 	int primary_cac_timeout;
 	int secondary_cac_timeout;
 	int precac_timeout;
+	struct dfs_soc_priv_obj *dfs_soc_obj;
 
+	dfs_soc_obj = dfs->dfs_soc_obj;
+	dfs = dfs_soc_obj->dfs_priv[dfs_soc_obj->cur_precac_dfs_index].dfs;
 #define EXTRA_TIME_IN_SEC 5
-	dfs->dfs_precac_timer_running = 1;
+	dfs_soc_obj->dfs_precac_timer_running = 1;
 
 	/*
 	 * Get the first primary ieee chan in the HT80 band and find the channel
@@ -823,7 +1126,7 @@
 
 	dfs_debug(dfs, WLAN_DEBUG_DFS,
 		"precactimeout = %d", (precac_timeout)*1000);
-	qdf_timer_mod(&dfs->dfs_precac_timer, (precac_timeout) * 1000);
+	qdf_timer_mod(&dfs_soc_obj->dfs_precac_timer, (precac_timeout) * 1000);
 }
 
 void dfs_print_precaclists(struct wlan_dfs *dfs)
@@ -1072,6 +1375,39 @@
 }
 #endif
 
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_find_vht80_chan_for_agile_precac(struct wlan_dfs *dfs,
+					  uint8_t *ch_freq,
+					  uint8_t ch_freq_seg1,
+					  uint8_t ch_freq_seg2)
+{
+	uint8_t ieee_freq;
+
+	dfs->dfs_soc_obj->ocac_status = OCAC_RESET;
+	ieee_freq = dfs_get_freq_from_precac_required_list(
+				dfs,
+				ch_freq_seg1);
+	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+		 "ieee_freq: %d  ch_freq_seg1: %d , ch_freq_seg2 : %d ",
+		 ieee_freq, ch_freq_seg1, ch_freq_seg2);
+	if (ieee_freq == ch_freq_seg2 && ieee_freq != 0)
+		ieee_freq = dfs_get_freq_from_precac_required_list(
+				dfs,
+				ch_freq_seg2);
+	if (ieee_freq) {
+		dfs->dfs_agile_precac_freq = ieee_freq;
+		/* Start the pre_cac_timer */
+		dfs_start_agile_precac_timer(dfs,
+					     dfs->dfs_agile_precac_freq,
+					     dfs->dfs_soc_obj->ocac_status);
+	} else {
+		dfs->dfs_agile_precac_freq = 0;
+	}
+
+	*ch_freq = dfs->dfs_agile_precac_freq;
+}
+#endif
+
 void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
 				    uint32_t chan_mode,
 				    uint8_t ch_freq_seg1,
@@ -1089,7 +1425,7 @@
 	dfs_debug(dfs, WLAN_DEBUG_DFS,
 		  "precac_secondary_freq = %u precac_running = %u",
 		  dfs->dfs_precac_secondary_freq,
-		  dfs->dfs_precac_timer_running);
+		  dfs->dfs_soc_obj->dfs_precac_timer_running);
 
 	/*
 	 * If Pre-CAC is enabled then find a center frequency for
@@ -1103,7 +1439,7 @@
 		 * channel. If precac timer is not running then try to
 		 * find a new channel from precac-required-list.
 		 */
-		if (dfs->dfs_precac_timer_running) {
+		if (dfs->dfs_soc_obj->dfs_precac_timer_running) {
 			/*
 			 * Primary and secondary VHT80 cannot be the
 			 * same. Therefore exclude the primary
@@ -1191,41 +1527,137 @@
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_lmac_if_target_tx_ops *tx_ops;
 	uint32_t target_type;
+	struct target_psoc_info *tgt_hdl;
+	struct tgt_info *info;
 
 	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
 	if (!psoc) {
 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "psoc is NULL");
 		dfs->dfs_precac_enable = 0;
+		dfs->dfs_agile_precac_enable = 0;
 		return;
 	}
 
 	tx_ops = &psoc->soc_cb.tx_ops.target_tx_ops;
 	target_type = lmac_get_target_type(dfs->dfs_pdev_obj);
 
+	tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(psoc);
+	if (!tgt_hdl) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "target_psoc_info is null");
+		return;
+	}
+
+	info = (struct tgt_info *)(&tgt_hdl->info);
+
+	if (!info) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "tgt_info is null");
+		return;
+	}
+
 	/*
 	 * If
 	 * 1) The chip is CASCADE,
-	 * 3) The user has enabled Pre-CAC and
-	 * 4) The regdomain the ETSI,
+	 * 2) The user has enabled Pre-CAC and
+	 * 3) The regdomain the ETSI,
 	 * then enable preCAC.
+	 *
+	 * OR
+	 *
+	 * If
+	 * 1) The chip has agile_capability enabled
+	 * 2) The user has enabled Pre-CAC and
+	 * 3) The regdomain the ETSI,
+	 * then enable Agile preCAC.
 	 */
+
 	if ((1 == value) && tx_ops->tgt_is_tgt_type_qca9984(target_type) &&
 	    (utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_ETSI_DOMAIN)) {
 		dfs->dfs_precac_enable = value;
+	} else if ((1 == value) && (info->wlan_res_cfg.agile_capability == 1) &&
+		(utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_ETSI_DOMAIN)) {
+		dfs->dfs_agile_precac_enable = value;
 	} else {
+		dfs->dfs_agile_precac_enable = 0;
 		dfs->dfs_precac_enable = 0;
 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "preCAC disabled");
 	}
+
 	if (dfs_is_precac_timer_running(dfs)) {
 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
 			 "Precac flag changed. Cancel the precac timer");
 		dfs_cancel_precac_timer(dfs);
+		dfs->dfs_soc_obj->precac_state_started = 0;
 	}
 }
 
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_agile_precac_start(struct wlan_dfs *dfs)
+{
+	uint8_t agile_freq = 0;
+	uint8_t ocac_status = 0;
+	struct dfs_soc_priv_obj *dfs_soc_obj;
+	uint8_t cur_dfs_idx;
+
+	dfs_soc_obj = dfs->dfs_soc_obj;
+	/*
+	 * Initiate first call to start preCAC here, for agile_freq as 0,
+	 * and ocac_status as 0
+	 */
+
+	qdf_info("%s : %d agile_precac_started: %d",
+		 __func__, __LINE__,
+		dfs_soc_obj->precac_state_started);
+
+	if (!dfs_soc_obj->precac_state_started)
+		dfs_soc_obj->cur_precac_dfs_index = dfs->dfs_psoc_idx;
+
+	cur_dfs_idx = dfs_soc_obj->cur_precac_dfs_index;
+	dfs_soc_obj->dfs_priv[cur_dfs_idx].agile_precac_active = true;
+	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+		 " setting true to cur_precac_dfs_index = %d, dfs: %pK",
+		 dfs_soc_obj->cur_precac_dfs_index,
+		 dfs->dfs_soc_obj->dfs_priv[cur_dfs_idx].dfs);
+
+	if (!dfs->dfs_soc_obj->precac_state_started) {
+		qdf_info("%s : %d Initiated agile precac",
+			 __func__, __LINE__);
+		dfs->dfs_soc_obj->precac_state_started = true;
+		dfs_start_agile_precac_timer(dfs,
+					     agile_freq,
+					     ocac_status);
+	}
+}
+#endif
+
 uint32_t dfs_get_precac_enable(struct wlan_dfs *dfs)
 {
-	return dfs->dfs_precac_enable;
+	struct wlan_objmgr_psoc *psoc;
+	struct target_psoc_info *tgt_hdl;
+	uint32_t retval = 0;
+	struct tgt_info *info;
+
+	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+	if (!psoc) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "psoc is NULL");
+		dfs->dfs_agile_precac_enable = 0;
+		retval = 0;
+	}
+
+	tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(psoc);
+
+	info = (struct tgt_info *)(&tgt_hdl->info);
+	if (!tgt_hdl) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "target_psoc_info is null");
+		dfs->dfs_agile_precac_enable = 0;
+		retval = 0;
+	}
+
+	if (info->wlan_res_cfg.agile_capability == 0)
+		retval = dfs->dfs_precac_enable;
+	else
+		retval = dfs->dfs_agile_precac_enable;
+
+	return retval;
 }
 
 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
diff --git a/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm_actions.c b/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm_actions.c
index 79e01d0..1b840a4 100644
--- a/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm_actions.c
+++ b/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm_actions.c
@@ -217,15 +217,13 @@
 		if ((!pdev_mlme->restart_pend_vdev_bmap[0] &&
 		     !pdev_mlme->restart_pend_vdev_bmap[1]) &&
 		    (!pdev_mlme->restart_send_vdev_bmap[0] &&
-		     !pdev_mlme->restart_send_vdev_bmap[1]))
+		     !pdev_mlme->restart_send_vdev_bmap[1])) {
 			wlan_pdev_mlme_op_clear
 					(pdev,
 					 WLAN_PDEV_OP_RESTART_INPROGRESS);
 			wlan_pdev_mlme_op_clear(pdev,
 						WLAN_PDEV_OP_MBSSID_RESTART);
-
-	} else {
-		status = QDF_STATUS_SUCCESS;
+		}
 	}
 	qdf_spin_unlock_bh(&pdev_mlme->vdev_restart_lock);
 
diff --git a/wmi/inc/wmi_unified_ap_api.h b/wmi/inc/wmi_unified_ap_api.h
index edf3d01..aa552b9 100644
--- a/wmi/inc/wmi_unified_ap_api.h
+++ b/wmi/inc/wmi_unified_ap_api.h
@@ -56,7 +56,7 @@
 				struct peer_update_wds_entry_params *param);
 
 QDF_STATUS wmi_unified_vdev_set_neighbour_rx_cmd_send(void *wmi_hdl,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct set_neighbour_rx_params *param);
 
 QDF_STATUS wmi_unified_vdev_config_ratemask_cmd_send(void *wmi_hdl,
@@ -192,7 +192,7 @@
 #endif /* WLAN_SUPPORT_FILS */
 
 QDF_STATUS wmi_unified_set_qboost_param_cmd_send(void *wmi_hdl,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct set_qboost_params *param);
 
 QDF_STATUS wmi_unified_gpio_config_cmd_send(void *wmi_hdl,
diff --git a/wmi/inc/wmi_unified_smart_ant_api.h b/wmi/inc/wmi_unified_smart_ant_api.h
index 325d4fd..37636ba 100644
--- a/wmi/inc/wmi_unified_smart_ant_api.h
+++ b/wmi/inc/wmi_unified_smart_ant_api.h
@@ -31,15 +31,15 @@
 				struct smart_ant_rx_ant_params *param);
 
 QDF_STATUS wmi_unified_smart_ant_set_tx_ant_cmd_send(void *wmi_hdl,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_tx_ant_params *param);
 
 QDF_STATUS wmi_unified_smart_ant_set_training_info_cmd_send(void *wmi_hdl,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_training_info_params *param);
 
 QDF_STATUS wmi_unified_smart_ant_node_config_cmd_send(void *wmi_hdl,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_node_config_params *param);
 
 QDF_STATUS wmi_unified_set_ant_switch_tbl_cmd_send(void *wmi_hdl,
diff --git a/wmi/src/wmi_unified_ap_api.c b/wmi/src/wmi_unified_ap_api.c
index e51d4e2..6476b3a 100644
--- a/wmi/src/wmi_unified_ap_api.c
+++ b/wmi/src/wmi_unified_ap_api.c
@@ -199,7 +199,7 @@
  *  @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
  */
 QDF_STATUS wmi_unified_vdev_set_neighbour_rx_cmd_send(void *wmi_hdl,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct set_neighbour_rx_params *param)
 {
 	wmi_unified_t wmi = (wmi_unified_t) wmi_hdl;
@@ -878,7 +878,7 @@
  *  @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
  */
 QDF_STATUS wmi_unified_set_qboost_param_cmd_send(void *wmi_hdl,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct set_qboost_params *param)
 {
 	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
diff --git a/wmi/src/wmi_unified_ap_tlv.c b/wmi/src/wmi_unified_ap_tlv.c
index d11c703..3330ca4 100644
--- a/wmi/src/wmi_unified_ap_tlv.c
+++ b/wmi/src/wmi_unified_ap_tlv.c
@@ -596,7 +596,7 @@
  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
  */
 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle,
-					uint8_t macaddr[IEEE80211_ADDR_LEN],
+					uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 					struct set_neighbour_rx_params *param)
 {
 	wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd;
@@ -2015,7 +2015,7 @@
  */
 static QDF_STATUS
 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle,
-			      uint8_t macaddr[IEEE80211_ADDR_LEN],
+			      uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 			      struct set_qboost_params *param)
 {
 	WMI_QBOOST_CFG_CMD_fixed_param *cmd;
diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c
index b14e0d9..4a469f1 100644
--- a/wmi/src/wmi_unified_non_tlv.c
+++ b/wmi/src/wmi_unified_non_tlv.c
@@ -44,7 +44,7 @@
  * Return: 0 for success or error code
  */
 static QDF_STATUS send_vdev_create_cmd_non_tlv(wmi_unified_t wmi_handle,
-				 uint8_t macaddr[IEEE80211_ADDR_LEN],
+				 uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				 struct vdev_create_params *param)
 {
 	wmi_vdev_create_cmd *cmd;
@@ -270,7 +270,7 @@
  * Return: 0 for success or error code
  */
 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_non_tlv(wmi_unified_t wmi_handle,
-					uint8_t macaddr[IEEE80211_ADDR_LEN],
+					uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 					struct set_neighbour_rx_params *param)
 {
 	wmi_vdev_filter_nrp_config_cmd *cmd;
@@ -502,7 +502,7 @@
  * Return: 0 for success or error code
  */
 static QDF_STATUS send_peer_flush_tids_cmd_non_tlv(wmi_unified_t wmi_handle,
-					 uint8_t peer_addr[IEEE80211_ADDR_LEN],
+					 uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
 					 struct peer_flush_params *param)
 {
 	wmi_peer_flush_tids_cmd *cmd;
@@ -532,7 +532,7 @@
  */
 static QDF_STATUS send_peer_delete_cmd_non_tlv(wmi_unified_t wmi_handle,
 					uint8_t
-					peer_addr[IEEE80211_ADDR_LEN],
+					peer_addr[QDF_MAC_ADDR_SIZE],
 					uint8_t vdev_id)
 {
 	wmi_peer_delete_cmd *cmd;
@@ -616,7 +616,7 @@
  * Return: 0 for success or error code
  */
 static QDF_STATUS send_peer_param_cmd_non_tlv(wmi_unified_t wmi_handle,
-				uint8_t peer_addr[IEEE80211_ADDR_LEN],
+				uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
 				struct peer_set_params *param)
 {
 	wmi_peer_set_param_cmd *cmd;
@@ -651,7 +651,7 @@
  * Return: 0 for success or error code
  */
 static QDF_STATUS send_vdev_up_cmd_non_tlv(wmi_unified_t wmi_handle,
-				 uint8_t bssid[IEEE80211_ADDR_LEN],
+				 uint8_t bssid[QDF_MAC_ADDR_SIZE],
 				 struct vdev_up_params *param)
 {
 	wmi_vdev_up_cmd *cmd;
@@ -835,7 +835,7 @@
 {
 	wmi_peer_add_wds_entry_cmd *cmd;
 	wmi_buf_t buf;
-	uint8_t null_macaddr[IEEE80211_ADDR_LEN];
+	uint8_t null_macaddr[QDF_MAC_ADDR_SIZE];
 	int len = sizeof(wmi_peer_add_wds_entry_cmd);
 
 	buf = wmi_buf_alloc(wmi_handle, len);
@@ -843,7 +843,7 @@
 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
 		return QDF_STATUS_E_NOMEM;
 	}
-	qdf_mem_zero(null_macaddr, IEEE80211_ADDR_LEN);
+	qdf_mem_zero(null_macaddr, QDF_MAC_ADDR_SIZE);
 	cmd = (wmi_peer_add_wds_entry_cmd *)wmi_buf_data(buf);
 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->bridge_addr, &cmd->wds_macaddr);
 	WMI_CHAR_ARRAY_TO_MAC_ADDR(null_macaddr, &cmd->peer_macaddr);
@@ -1115,7 +1115,8 @@
 	int len = sizeof(wmi_pdev_set_param_cmd);
 
 	if ((param->param_id < wmi_pdev_param_max) &&
-		(wmi_handle->pdev_param[param->param_id]
+		wmi_handle->soc->pdev_param &&
+		(wmi_handle->soc->pdev_param[param->param_id]
 				!= WMI_UNAVAILABLE_PARAM)) {
 
 		buf = wmi_buf_alloc(wmi_handle, len);
@@ -1124,7 +1125,7 @@
 			return QDF_STATUS_E_FAILURE;
 		}
 		cmd = (wmi_pdev_set_param_cmd *)wmi_buf_data(buf);
-		cmd->param_id = wmi_handle->pdev_param[param->param_id];
+		cmd->param_id = wmi_handle->soc->pdev_param[param->param_id];
 		cmd->param_value = param->param_value;
 		return wmi_unified_cmd_send(wmi_handle, buf, len,
 			WMI_PDEV_SET_PARAM_CMDID);
@@ -1521,7 +1522,8 @@
 	int len = sizeof(wmi_vdev_set_param_cmd);
 
 	if ((param->param_id < wmi_vdev_param_max) &&
-		(wmi_handle->vdev_param[param->param_id] !=
+		wmi_handle->soc->vdev_param &&
+		(wmi_handle->soc->vdev_param[param->param_id] !=
 				WMI_UNAVAILABLE_PARAM)) {
 
 		buf = wmi_buf_alloc(wmi_handle, len);
@@ -1535,7 +1537,7 @@
 #else
 		cmd->vdev_id = param->if_id;
 #endif
-		cmd->param_id = wmi_handle->vdev_param[param->param_id];
+		cmd->param_id = wmi_handle->soc->vdev_param[param->param_id];
 		cmd->param_value = param->param_value;
 		return wmi_unified_cmd_send(wmi_handle, buf, len,
 				WMI_VDEV_SET_PARAM_CMDID);
@@ -1608,7 +1610,7 @@
  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
  */
 static QDF_STATUS send_stats_request_cmd_non_tlv(wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct stats_request_params *param)
 {
 	wmi_buf_t buf;
@@ -2606,7 +2608,7 @@
  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
  */
 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_non_tlv(wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_tx_ant_params *param)
 {
 	wmi_peer_sant_set_tx_antenna_cmd *cmd;
@@ -2656,7 +2658,7 @@
  */
 static QDF_STATUS send_smart_ant_set_training_info_cmd_non_tlv(
 				wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_training_info_params *param)
 {
 	wmi_peer_sant_set_train_antenna_cmd *cmd;
@@ -2709,7 +2711,7 @@
  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
  */
 static QDF_STATUS send_smart_ant_set_node_config_cmd_non_tlv(wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_node_config_params *param)
 {
 	wmi_peer_sant_set_node_config_ops_cmd *cmd;
@@ -3252,7 +3254,7 @@
  */
 static QDF_STATUS
 send_addba_clearresponse_cmd_non_tlv(wmi_unified_t wmi_handle,
-			uint8_t macaddr[IEEE80211_ADDR_LEN],
+			uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 			struct addba_clearresponse_params *param)
 {
 	wmi_addba_clear_resp_cmd *cmd;
@@ -3282,7 +3284,7 @@
  */
 static QDF_STATUS
 send_addba_send_cmd_non_tlv(wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct addba_send_params *param)
 {
 	wmi_addba_send_cmd *cmd;
@@ -3314,7 +3316,7 @@
  */
 static QDF_STATUS
 send_delba_send_cmd_non_tlv(wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct delba_send_params *param)
 {
 	wmi_delba_send_cmd *cmd;
@@ -3348,7 +3350,7 @@
  */
 static QDF_STATUS
 send_addba_setresponse_cmd_non_tlv(wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct addba_setresponse_params *param)
 {
 	wmi_addba_setresponse_cmd *cmd;
@@ -3381,7 +3383,7 @@
  */
 static QDF_STATUS
 send_singleamsdu_cmd_non_tlv(wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct singleamsdu_params *param)
 {
 	wmi_send_singleamsdu_cmd *cmd;
@@ -3413,7 +3415,7 @@
  */
 static QDF_STATUS
 send_set_qboost_param_cmd_non_tlv(wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct set_qboost_params *param)
 {
 
@@ -5278,7 +5280,7 @@
 		WMI_SET_CHANNEL_FLAG(w_chan, WMI_CHAN_FLAG_DFS);
 
 	WMI_CHAR_ARRAY_TO_MAC_ADDR(((uint8_t *)peer), &body->dest_mac);
-	qdf_mem_set(spoof, IEEE80211_ADDR_LEN, 0);
+	qdf_mem_set(spoof, QDF_MAC_ADDR_SIZE, 0);
 	WMI_CHAR_ARRAY_TO_MAC_ADDR(((uint8_t *)param->spoof_mac_addr),
 		&body->spoof_bssid);
 
@@ -5379,7 +5381,7 @@
 		/* Convert num_vaps to octets:
 		   6*Num_of_vap + 1 (Max BSSID Indicator field) */
 		param->colocated_bss[1] =
-			(param->colocated_bss[1]*IEEE80211_ADDR_LEN)+1;
+			(param->colocated_bss[1]*QDF_MAC_ADDR_SIZE)+1;
 		colocated_bss_len =  param->colocated_bss[1]+2;
 		qdf_mem_copy(rtt_req->colocated_bssids_info,
 				param->colocated_bss,
@@ -10069,8 +10071,10 @@
 	wmi_handle->soc->svc_ids = &svc_ids[0];
 	populate_non_tlv_service(wmi_handle->services);
 	populate_non_tlv_events_id(wmi_handle->wmi_events);
-	populate_pdev_param_non_tlv(wmi_handle->pdev_param);
-	populate_vdev_param_non_tlv(wmi_handle->vdev_param);
+	if (wmi_handle->soc->pdev_param)
+		populate_pdev_param_non_tlv(wmi_handle->soc->pdev_param);
+	if (wmi_handle->soc->vdev_param)
+		populate_vdev_param_non_tlv(wmi_handle->soc->vdev_param);
 
 #ifdef WMI_INTERFACE_EVENT_LOGGING
 	wmi_handle->soc->buf_offset_command = 0;
diff --git a/wmi/src/wmi_unified_smart_ant_api.c b/wmi/src/wmi_unified_smart_ant_api.c
index 5319b1b..99e13de 100644
--- a/wmi/src/wmi_unified_smart_ant_api.c
+++ b/wmi/src/wmi_unified_smart_ant_api.c
@@ -84,7 +84,7 @@
  *  @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
  */
 QDF_STATUS wmi_unified_smart_ant_set_tx_ant_cmd_send(void *wmi_hdl,
-		uint8_t macaddr[IEEE80211_ADDR_LEN],
+		uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_tx_ant_params *param)
 {
 	wmi_unified_t wmi = (wmi_unified_t) wmi_hdl;
@@ -104,7 +104,7 @@
  *  @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
  */
 QDF_STATUS wmi_unified_smart_ant_set_training_info_cmd_send(void *wmi_hdl,
-		uint8_t macaddr[IEEE80211_ADDR_LEN],
+		uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_training_info_params *param)
 {
 	wmi_unified_t wmi = (wmi_unified_t) wmi_hdl;
@@ -125,7 +125,7 @@
  *  @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
  */
 QDF_STATUS wmi_unified_smart_ant_node_config_cmd_send(void *wmi_hdl,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_node_config_params *param)
 {
 	wmi_unified_t wmi = (wmi_unified_t) wmi_hdl;
diff --git a/wmi/src/wmi_unified_smart_ant_tlv.c b/wmi/src/wmi_unified_smart_ant_tlv.c
index 4487947..33a792f 100644
--- a/wmi/src/wmi_unified_smart_ant_tlv.c
+++ b/wmi/src/wmi_unified_smart_ant_tlv.c
@@ -186,7 +186,7 @@
  *  @return QDF_STATUS_SUCCESS  on success and -ve on failure.
  */
 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_tx_ant_params *param)
 {
 	wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd;
@@ -319,7 +319,7 @@
  */
 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv(
 				wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_training_info_params *param)
 {
 	wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd;
@@ -402,7 +402,7 @@
  */
 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv(
 				wmi_unified_t wmi_handle,
-				uint8_t macaddr[IEEE80211_ADDR_LEN],
+				uint8_t macaddr[QDF_MAC_ADDR_SIZE],
 				struct smart_ant_node_config_params *param)
 {
 	wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd;