Merge "qca-wifi: Add cmd support for WNM and RRM filter"
diff --git a/dp/src/dp_rate_stats.c b/dp/src/dp_rate_stats.c
index 089e026..a097073 100644
--- a/dp/src/dp_rate_stats.c
+++ b/dp/src/dp_rate_stats.c
@@ -374,8 +374,8 @@
 
 		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));
+			qdf_warn("peer_mac:  " QDF_MAC_ADDR_FMT,
+				 QDF_MAC_ADDR_REF(ppdu_user->mac_addr));
 			STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->tx_ctx_lock);
 			continue;
 		}
@@ -448,8 +448,8 @@
 
 		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));
+			qdf_warn("peer_mac:  " QDF_MAC_ADDR_FMT,
+				 QDF_MAC_ADDR_REF(ppdu_user->mac_addr));
 			STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock);
 			continue;
 		}
@@ -531,8 +531,8 @@
 
 		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));
+			qdf_warn("peer_mac:  " QDF_MAC_ADDR_FMT,
+				 QDF_MAC_ADDR_REF(cdp_rx_ppdu->mac_addr));
 			STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->rx_ctx_lock);
 			continue;
 		}
@@ -658,8 +658,8 @@
 
 		if (qdf_unlikely(!stats_ctx)) {
 			qdf_debug("peer rate stats ctx is NULL, investigate");
-			qdf_debug("peer_mac: " QDF_MAC_ADDR_STR,
-				 QDF_MAC_ADDR_ARRAY(ppdu_user->mac_addr));
+			qdf_debug("peer_mac: " QDF_MAC_ADDR_FMT,
+				 QDF_MAC_ADDR_REF(ppdu_user->mac_addr));
 			STATS_CTX_LOCK_RELEASE(&soc_stats_ctx->tx_ctx_lock);
 			continue;
 		}
diff --git a/dp/wifi3.0/dp_full_mon.c b/dp/wifi3.0/dp_full_mon.c
index 3a11d92..a4db3c8 100644
--- a/dp/wifi3.0/dp_full_mon.c
+++ b/dp/wifi3.0/dp_full_mon.c
@@ -62,7 +62,7 @@
 	uint32_t tlv_tag;
 	void *rx_tlv;
 	struct hal_rx_ppdu_info *ppdu_info;
-	enum dp_mon_reap_status status = dp_mon_status_match;
+	enum dp_mon_reap_status status = DP_MON_STATUS_MATCH;
 	QDF_STATUS buf_status;
 	uint32_t ppdu_id_diff;
 
@@ -94,7 +94,7 @@
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s %d : HAL SRNG entry is NULL srng:-- %pK",
 			  __func__, __LINE__, mon_status_srng);
-		status = dp_mon_status_replenish;
+		status = DP_MON_STATUS_REPLENISH;
 		goto done;
 	}
 
@@ -109,7 +109,7 @@
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s %d : buf addr is NULL -- %pK",
 			  __func__, __LINE__, mon_status_srng);
-		status = dp_mon_status_replenish;
+		status = DP_MON_STATUS_REPLENISH;
 		goto done;
 	}
 
@@ -135,8 +135,28 @@
 			  FL("Monitor status ring: DMA is not done "
 			     "for nbuf: %pK buf_addr: %llx"),
 			     status_nbuf, buf_paddr);
-		pdev->rx_mon_stats.tlv_tag_status_err++;
-		status = dp_mon_status_no_dma;
+		status = dp_rx_mon_handle_status_buf_done(pdev,
+							  mon_status_srng);
+
+		if (status == DP_MON_STATUS_REPLENISH) {
+			union dp_rx_desc_list_elem_t *desc_list = NULL;
+			union dp_rx_desc_list_elem_t *tail = NULL;
+
+			/* If this is DMA not done WAR case,
+			 * free buffer and current SW descriptor and
+			 * make buf_addr_info NULL, so that call to
+			 * dp_rx_mon_status_process() replenishes entry to
+			 * status ring
+			 */
+			qdf_nbuf_free(status_nbuf);
+			dp_rx_add_to_free_desc_list(&desc_list,
+						&tail, rx_desc);
+			dp_rx_add_desc_list_to_free_list(soc, &desc_list,
+						&tail, mac_id, rx_desc_pool);
+			hal_rxdma_buff_addr_info_set(
+						ring_entry,
+						0, 0, HAL_RX_BUF_RBM_SW3_BM);
+		}
 		goto done;
 	}
 
@@ -156,22 +176,22 @@
 	}
 
 	if (pdev->mon_desc->ppdu_id < pdev->mon_desc->status_ppdu_id) {
-		status = dp_mon_status_lead;
+		status = DP_MON_STATUS_LEAD;
 
 		/* For wrap around case */
 		ppdu_id_diff = pdev->mon_desc->status_ppdu_id -
 			       pdev->mon_desc->ppdu_id;
 
 		if (ppdu_id_diff > DP_RX_MON_PPDU_ID_WRAP)
-			status = dp_mon_status_lag;
+			status = DP_MON_STATUS_LAG;
 
 	} else if (pdev->mon_desc->ppdu_id > pdev->mon_desc->status_ppdu_id) {
-		status = dp_mon_status_lag;
+		status = DP_MON_STATUS_LAG;
 		/* For wrap around case */
 		ppdu_id_diff = pdev->mon_desc->ppdu_id -
 			       pdev->mon_desc->status_ppdu_id;
 		if (ppdu_id_diff > DP_RX_MON_PPDU_ID_WRAP)
-			status = dp_mon_status_lead;
+			status = DP_MON_STATUS_LEAD;
 	}
 
 	if ((pdev->mon_desc->status_buf.paddr != buf_paddr) ||
@@ -336,14 +356,14 @@
 
 	status = dp_rx_mon_status_buf_validate(pdev, int_ctx, mac_id);
 	switch (status) {
-		case dp_mon_status_no_dma:
+		case DP_MON_STATUS_NO_DMA:
 			/* If DMA is not done for status ring entry,
 			 * hold on to monitor destination ring and
 			 * deliver current ppdu data once DMA is done.
 			 */
 			pdev->hold_mon_dest_ring = true;
 			break;
-		case dp_mon_status_lag:
+		case DP_MON_STATUS_LAG:
 			/* If status_ppdu_id is lagging behind destination,
 			 * a. Hold on to destination ring
 			 * b. Drop status ppdus until ppdu id matches
@@ -354,7 +374,7 @@
 			pdev->rx_mon_stats.ppdu_id_mismatch++;
 			pdev->rx_mon_stats.status_ppdu_drop++;
 			break;
-		case dp_mon_status_lead:
+		case DP_MON_STATUS_LEAD:
 			/* If status_ppdu_id is leading ahead destination,
 			 * a. Drop destination ring ppdu until ppdu_id matches
 			 * b. Unhold monitor destination ring so status ppdus
@@ -367,11 +387,11 @@
 			pdev->rx_mon_stats.ppdu_id_mismatch++;
 			pdev->rx_mon_stats.dest_ppdu_drop++;
 			break;
-		case dp_mon_status_replenish:
+		case DP_MON_STATUS_REPLENISH:
 			/* If status ring hp entry is NULL, replenish it */
 			work_done = dp_rx_mon_status_process(soc,  int_ctx, mac_id, 1);
 			break;
-		case dp_mon_status_match:
+		case DP_MON_STATUS_MATCH:
 			/* If status ppdu id matches with destnation,
 			 * unhold monitor destination ring and deliver ppdu
 			 */
@@ -384,11 +404,11 @@
 	/* If status ring is lagging behind detination ring,
 	 * reap only one status buffer
 	 */
-	if (status == dp_mon_status_lag)
+	if (status == DP_MON_STATUS_LAG)
 		status_buf_count = 1;
 
-	if (status == dp_mon_status_lag ||
-	    status == dp_mon_status_match) {
+	if (status == DP_MON_STATUS_LAG ||
+	    status == DP_MON_STATUS_MATCH) {
 		work_done = dp_rx_mon_status_process(soc,
 						     int_ctx,
 						     mac_id,
@@ -497,7 +517,10 @@
 			if (drop_mpdu) {
 				dp_rx_mon_buffer_free(rx_desc);
 				msdu = NULL;
-				desc_info->msdu_count--;
+				/*
+				 * Dont rely on msdu_cnt in case of rxdma error
+				 * Dont decrement msdu_cnt
+				 */
 				goto next_msdu;
 			}
 
@@ -636,14 +659,14 @@
 		status = dp_rx_mon_status_buf_validate(pdev, int_ctx, mac_id);
 
 		switch (status) {
-			case dp_mon_status_no_dma:
+			case DP_MON_STATUS_NO_DMA:
 			/* If DMA is not done for status ring entry,
 			 * hold on to monitor destination ring and
 			 * deliver current ppdu data once DMA is done.
 			 */
 			pdev->hold_mon_dest_ring = true;
 			break;
-			case dp_mon_status_lag:
+			case DP_MON_STATUS_LAG:
 			/* If status_ppdu_id is lagging behind destination,
 			 * a. Hold on to destination ring
 			 * b. Drop status ppdus until ppdu id matches
@@ -654,7 +677,7 @@
 			pdev->rx_mon_stats.ppdu_id_mismatch++;
 			pdev->rx_mon_stats.status_ppdu_drop++;
 			break;
-			case dp_mon_status_lead:
+			case DP_MON_STATUS_LEAD:
 			/* If status_ppdu_id is leading ahead destination,
 			 * a. Drop destination ring ppdu until ppdu_id matches
 			 * b. Unhold monitor destination ring so status ppdus
@@ -667,11 +690,11 @@
 			pdev->rx_mon_stats.ppdu_id_mismatch++;
 			pdev->rx_mon_stats.dest_ppdu_drop++;
 			break;
-			case dp_mon_status_replenish:
+			case DP_MON_STATUS_REPLENISH:
 			/* If status ring hp entry is NULL, replenish it */
 			work = dp_rx_mon_status_process(soc, int_ctx, mac_id, 1);
 			break;
-			case dp_mon_status_match:
+			case DP_MON_STATUS_MATCH:
 			/* If status ppdu id matches with destnation,
 			 * unhold monitor destination ring and deliver ppdu
 			 */
@@ -686,12 +709,12 @@
 		 * available for radiotap construction, so return and
 		 * check for status on next interrupt
 		 */
-		if ((status == dp_mon_status_no_dma) ||
-		    (status == dp_mon_status_replenish)) {
+		if ((status == DP_MON_STATUS_NO_DMA) ||
+		    (status == DP_MON_STATUS_REPLENISH)) {
 			return work_done;
 		}
 
-		if (status == dp_mon_status_lag) {
+		if (status == DP_MON_STATUS_LAG) {
 			work = dp_rx_mon_status_process(soc, int_ctx, mac_id, 1);
 
 			if (!work)
diff --git a/dp/wifi3.0/dp_full_mon.h b/dp/wifi3.0/dp_full_mon.h
index 139a075..d249f6e 100644
--- a/dp/wifi3.0/dp_full_mon.h
+++ b/dp/wifi3.0/dp_full_mon.h
@@ -57,21 +57,4 @@
 	}
 	return QDF_STATUS_E_FAILURE;
 }
-
-/*
- * dp_mon_reap_status - monitor status ring ppdu status
- *
- * dp_mon_status_no_dma - DMA not done for status ring entry
- * dp_mon_status_match - status and dest ppdu id mathes
- * dp_mon_status_lag - status ppdu id is lagging
- * dp_mon_status_lead - status ppdu id is leading
- * dp_mon_status_replenish - status ring entry is NULL
- */
-enum dp_mon_reap_status {
-	dp_mon_status_no_dma,
-	dp_mon_status_match,
-	dp_mon_status_lag,
-	dp_mon_status_lead,
-	dp_mon_status_replenish
-};
 #endif /* _DP_FULL_MON_H_ */
diff --git a/dp/wifi3.0/dp_tx_capture.c b/dp/wifi3.0/dp_tx_capture.c
index ce3cb29..fee5546 100644
--- a/dp/wifi3.0/dp_tx_capture.c
+++ b/dp/wifi3.0/dp_tx_capture.c
@@ -115,6 +115,8 @@
 /* Maximum number of retries */
 #define MAX_RETRY_Q_COUNT 20
 
+#define DP_PEER_TX_TID_INIT_DONE_BIT 0
+
 #ifdef WLAN_TX_PKT_CAPTURE_ENH
 
 /* stats counter */
@@ -489,8 +491,11 @@
 
 	for (tid = 0; tid < DP_MAX_TIDS; tid++) {
 		tx_tid = &peer->tx_capture.tx_tid[tid];
-		if (tx_tid->init_done)
+
+		if (qdf_atomic_test_and_set_bit(DP_PEER_TX_TID_INIT_DONE_BIT,
+						&tx_tid->tid_flags))
 			continue;
+
 		tx_tid->tid = tid;
 		qdf_nbuf_queue_init(&tx_tid->defer_msdu_q);
 		qdf_nbuf_queue_init(&tx_tid->msdu_comp_q);
@@ -510,6 +515,8 @@
 			for (i = 0; i < tid; i++) {
 				tx_tid = &peer->tx_capture.tx_tid[i];
 				qdf_mem_free(tx_tid->xretry_ppdu);
+				qdf_atomic_clear_bit(DP_PEER_TX_TID_INIT_DONE_BIT,
+							&tx_tid->tid_flags);
 			}
 			QDF_ASSERT(0);
 			return;
@@ -518,7 +525,6 @@
 		/* spinlock create */
 		qdf_spinlock_create(&tx_tid->tid_lock);
 		qdf_spinlock_create(&tx_tid->tasklet_tid_lock);
-		tx_tid->init_done = 1;
 	}
 
 	peer->tx_capture.is_tid_initialized = 1;
@@ -572,6 +578,11 @@
 
 	for (tid = 0; tid < DP_MAX_TIDS; tid++) {
 		tx_tid = &peer->tx_capture.tx_tid[tid];
+
+		if (!qdf_atomic_test_and_clear_bit(DP_PEER_TX_TID_INIT_DONE_BIT,
+						&tx_tid->tid_flags))
+			continue;
+
 		xretry_ppdu = tx_tid->xretry_ppdu;
 		xretry_user = &xretry_ppdu->user[0];
 
@@ -2576,8 +2587,6 @@
 QDF_STATUS dp_send_dummy_mpdu_info_to_stack(struct dp_pdev *pdev,
 					    void *desc, uint8_t usr_idx)
 {
-	struct dp_peer *peer;
-	struct dp_vdev *vdev = NULL;
 	struct cdp_tx_completion_ppdu *ppdu_desc = desc;
 	struct cdp_tx_completion_ppdu_user *user = &ppdu_desc->user[usr_idx];
 	struct ieee80211_ctlframe_addr2 *wh_min;
@@ -2663,20 +2672,31 @@
 		qdf_nbuf_set_pktlen(tx_capture_info.mpdu_nbuf,
 				    sizeof(struct ieee80211_frame_min_one));
 	else {
+		struct dp_peer *peer;
+		struct dp_vdev *vdev = NULL;
+
 		peer = dp_peer_get_ref_by_id(pdev->soc, user->peer_id,
 					     DP_MOD_ID_TX_CAPTURE);
 		if (peer) {
 			vdev = peer->vdev;
+
+			if (vdev)
+				qdf_mem_copy(wh_min->i_addr2,
+					     vdev->mac_addr.raw,
+					     QDF_MAC_ADDR_SIZE);
 			dp_peer_unref_delete(peer, DP_MOD_ID_TX_CAPTURE);
 		} else {
 			vdev =
-			dp_get_vdev_from_soc_vdev_id_wifi3(pdev->soc,
-							   ppdu_desc->vdev_id);
+			dp_vdev_get_ref_by_id(pdev->soc, ppdu_desc->vdev_id,
+					      DP_MOD_ID_TX_CAPTURE);
+			if (vdev) {
+				qdf_mem_copy(wh_min->i_addr2,
+					     vdev->mac_addr.raw,
+					     QDF_MAC_ADDR_SIZE);
+				dp_vdev_unref_delete(pdev->soc, vdev,
+						     DP_MOD_ID_TX_CAPTURE);
+			}
 		}
-		if (vdev)
-			qdf_mem_copy(wh_min->i_addr2,
-				     vdev->mac_addr.raw,
-				     QDF_MAC_ADDR_SIZE);
 		qdf_nbuf_set_pktlen(tx_capture_info.mpdu_nbuf, sizeof(*wh_min));
 	}
 
@@ -2710,7 +2730,7 @@
 static
 void dp_send_dummy_rts_cts_frame(struct dp_pdev *pdev,
 				 struct cdp_tx_completion_ppdu *cur_ppdu_desc,
-				 uint8_t usr_idx)
+				 uint8_t usr_id)
 {
 	struct cdp_tx_completion_ppdu *ppdu_desc;
 	struct dp_pdev_tx_capture *ptr_tx_cap;
@@ -2725,7 +2745,7 @@
 	ppdu_desc->channel = cur_ppdu_desc->channel;
 	ppdu_desc->num_mpdu = 1;
 	ppdu_desc->num_msdu = 1;
-	ppdu_desc->user[usr_idx].ppdu_type = HTT_PPDU_STATS_PPDU_TYPE_SU;
+	ppdu_desc->user[usr_id].ppdu_type = HTT_PPDU_STATS_PPDU_TYPE_SU;
 	ppdu_desc->bar_num_users = 0;
 	ppdu_desc->num_users = 1;
 
@@ -2744,22 +2764,22 @@
 		ppdu_desc->ppdu_end_timestamp =
 				cur_ppdu_desc->ppdu_end_timestamp;
 		ppdu_desc->tx_duration = cur_ppdu_desc->tx_duration;
-		ppdu_desc->user[usr_idx].peer_id =
-				cur_ppdu_desc->user[usr_idx].peer_id;
+		ppdu_desc->user[usr_id].peer_id =
+				cur_ppdu_desc->user[usr_id].peer_id;
 		ppdu_desc->frame_ctrl = (IEEE80211_FC0_SUBTYPE_RTS |
 					 IEEE80211_FC0_TYPE_CTL);
-		qdf_mem_copy(&ppdu_desc->user[usr_idx].mac_addr,
-			     &cur_ppdu_desc->user[usr_idx].mac_addr,
+		qdf_mem_copy(&ppdu_desc->user[usr_id].mac_addr,
+			     &cur_ppdu_desc->user[usr_id].mac_addr,
 			     QDF_MAC_ADDR_SIZE);
 
-		dp_send_dummy_mpdu_info_to_stack(pdev, ppdu_desc, usr_idx);
+		dp_send_dummy_mpdu_info_to_stack(pdev, ppdu_desc, usr_id);
 	}
 
 	if ((rts_send && cur_ppdu_desc->rts_success) ||
 	    cur_ppdu_desc->mprot_type == SEND_WIFICTS2SELF_E) {
 		uint16_t peer_id;
 
-		peer_id = cur_ppdu_desc->user[usr_idx].peer_id;
+		peer_id = cur_ppdu_desc->user[usr_id].peer_id;
 		/* send dummy CTS frame */
 		ppdu_desc->htt_frame_type = HTT_STATS_FTYPE_SGEN_CTS;
 		ppdu_desc->frame_type = CDP_PPDU_FTYPE_CTRL;
@@ -2771,25 +2791,33 @@
 				cur_ppdu_desc->ppdu_end_timestamp;
 		ppdu_desc->tx_duration = cur_ppdu_desc->tx_duration -
 					 (RTS_INTERVAL + SIFS_INTERVAL);
-		ppdu_desc->user[usr_idx].peer_id = peer_id;
+		ppdu_desc->user[usr_id].peer_id = peer_id;
 		peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
 					     DP_MOD_ID_TX_CAPTURE);
 		if (peer) {
 			vdev = peer->vdev;
+			if (vdev)
+				qdf_mem_copy(&ppdu_desc->user[usr_id].mac_addr,
+					     vdev->mac_addr.raw,
+					     QDF_MAC_ADDR_SIZE);
 			dp_peer_unref_delete(peer, DP_MOD_ID_TX_CAPTURE);
 		} else {
 			uint8_t vdev_id;
 
 			vdev_id = ppdu_desc->vdev_id;
-			vdev = dp_get_vdev_from_soc_vdev_id_wifi3(pdev->soc,
-								  vdev_id);
+			vdev = dp_vdev_get_ref_by_id(pdev->soc, vdev_id,
+						     DP_MOD_ID_TX_CAPTURE);
+			if (vdev) {
+				qdf_mem_copy(&ppdu_desc->user[usr_id].mac_addr,
+					     vdev->mac_addr.raw,
+					     QDF_MAC_ADDR_SIZE);
+				dp_vdev_unref_delete(pdev->soc, vdev,
+						     DP_MOD_ID_TX_CAPTURE);
+			}
 		}
 
-		if (vdev)
-			qdf_mem_copy(&ppdu_desc->user[usr_idx].mac_addr,
-				     vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE);
 
-		dp_send_dummy_mpdu_info_to_stack(pdev, ppdu_desc, usr_idx);
+		dp_send_dummy_mpdu_info_to_stack(pdev, ppdu_desc, usr_id);
 	}
 }
 
@@ -6257,11 +6285,11 @@
 		/* initialize ppdu_desc_log to 1 */
 		ptr_log_info->ppdu_desc_log = 1;
 	} else {
-		/* if ppdu_desc log already 1 return success */
-		if (ptr_log_info->ppdu_desc_log)
+		/* if ppdu_desc log already 0 return success */
+		if (!ptr_log_info->ppdu_desc_log)
 			return QDF_STATUS_SUCCESS;
 
-		/* initialize ppdu_desc_log to 1 */
+		/* initialize ppdu_desc_log to 0 */
 		ptr_log_info->ppdu_desc_log = 0;
 	}
 	return QDF_STATUS_SUCCESS;
diff --git a/dp/wifi3.0/dp_tx_capture.h b/dp/wifi3.0/dp_tx_capture.h
index 5618d21..6e0e103 100644
--- a/dp/wifi3.0/dp_tx_capture.h
+++ b/dp/wifi3.0/dp_tx_capture.h
@@ -161,7 +161,7 @@
 	uint16_t first_data_seq_ctrl;
 	uint32_t mpdu_cnt;
 	uint32_t mpdu_fcs_ok_bitmap[QDF_MON_STATUS_MPDU_FCS_BMAP_NWORDS];
-	uint8_t init_done;
+	unsigned long tid_flags;
 };
 
 struct dp_peer_tx_capture {
diff --git a/dp/wifi3.0/dp_txrx_me.c b/dp/wifi3.0/dp_txrx_me.c
index b6d8b1d..215e6cb 100644
--- a/dp/wifi3.0/dp_txrx_me.c
+++ b/dp/wifi3.0/dp_txrx_me.c
@@ -210,6 +210,24 @@
 	return QDF_STATUS_E_FAILURE;
 }
 
+/**
+ * dp_tx_prepare_send_igmp_me(): Call to check igmp ,convert mcast to ucast
+ * @vdev: DP VDEV handle
+ * @nbuf: Multicast buffer
+ *
+ * Return: no of packets transmitted
+ */
+QDF_STATUS
+dp_tx_prepare_send_igmp_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
+{
+	if (dp_igmp_me_mcast_convert((struct cdp_soc_t *)(vdev->pdev->soc),
+				     vdev->vdev_id, vdev->pdev->pdev_id,
+				     nbuf) > 0)
+		return QDF_STATUS_SUCCESS;
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 /*
  * dp_tx_me_mem_free(): Function to free allocated memory in mcast enahncement
  * pdev: pointer to DP PDEV structure
@@ -249,15 +267,19 @@
  * @nbuf: Multicast nbuf
  * @newmac: Table of the clients to which packets have to be sent
  * @new_mac_cnt: No of clients
+ * @tid: desired tid
+ * @is_igmp: flag to indicate if packet is igmp
  *
  * return: no of converted packets
  */
 uint16_t
-dp_tx_me_send_convert_ucast(struct cdp_soc_t *soc, uint8_t vdev_id,
+dp_tx_me_send_convert_ucast(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 			    qdf_nbuf_t nbuf,
 			    uint8_t newmac[][QDF_MAC_ADDR_SIZE],
-			    uint8_t new_mac_cnt)
+			    uint8_t new_mac_cnt, uint8_t tid,
+			    bool is_igmp)
 {
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
 	struct dp_pdev *pdev;
 	qdf_ether_header_t *eh;
 	uint8_t *data;
@@ -280,31 +302,16 @@
 	qdf_dma_addr_t paddr_mcbuf = 0;
 	uint8_t empty_entry_mac[QDF_MAC_ADDR_SIZE] = {0};
 	QDF_STATUS status;
-	struct dp_vdev *vdev =
-		dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
-						   vdev_id);
+	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
+						     DP_MOD_ID_MCAST2UCAST);
 
-	if (!vdev) {
-		qdf_nbuf_free(nbuf);
-		return 1;
-	}
-
-	pdev = vdev->pdev;
-
-	if (!pdev) {
-		qdf_nbuf_free(nbuf);
-		return 1;
-	}
-
-	vdev = dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
-						  vdev_id);
 	if (!vdev)
-		return 1;
+		goto free_return;
 
 	pdev = vdev->pdev;
 
 	if (!pdev)
-		return 1;
+		goto free_return;
 
 	qdf_mem_zero(&msdu_info, sizeof(msdu_info));
 
@@ -421,19 +428,29 @@
 	}
 
 	if (!seg_info_head) {
-		goto free_return;
+		goto unmap_free_return;
 	}
 
 	msdu_info.u.sg_info.curr_seg = seg_info_head;
 	msdu_info.num_seg = new_mac_cnt;
 	msdu_info.frm_type = dp_tx_frm_me;
 
-	msdu_info.tid = HTT_INVALID_TID;
-	if (qdf_unlikely(vdev->mcast_enhancement_en > 0) &&
-	    qdf_unlikely(pdev->hmmc_tid_override_en))
-		msdu_info.tid = pdev->hmmc_tid;
+	if (tid == HTT_INVALID_TID) {
+		msdu_info.tid = HTT_INVALID_TID;
+		if (qdf_unlikely(vdev->mcast_enhancement_en > 0) &&
+		    qdf_unlikely(pdev->hmmc_tid_override_en))
+			msdu_info.tid = pdev->hmmc_tid;
+	} else {
+		msdu_info.tid = tid;
+	}
 
-	DP_STATS_INC(vdev, tx_i.mcast_en.ucast, new_mac_cnt);
+	if (is_igmp) {
+		DP_STATS_INC(vdev, tx_i.igmp_mcast_en.igmp_ucast_converted,
+			     new_mac_cnt);
+	} else {
+		DP_STATS_INC(vdev, tx_i.mcast_en.ucast, new_mac_cnt);
+	}
+
 	dp_tx_send_msdu_multiple(vdev, nbuf, &msdu_info);
 
 	while (seg_info_head->next) {
@@ -445,6 +462,7 @@
 
 	qdf_nbuf_unmap(pdev->soc->osdev, nbuf, QDF_DMA_TO_DEVICE);
 	qdf_nbuf_free(nbuf);
+	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_MCAST2UCAST);
 	return new_mac_cnt;
 
 fail_map:
@@ -459,8 +477,11 @@
 fail_seg_alloc:
 	dp_tx_me_mem_free(pdev, seg_info_head);
 
-free_return:
+unmap_free_return:
 	qdf_nbuf_unmap(pdev->soc->osdev, nbuf, QDF_DMA_TO_DEVICE);
+free_return:
+	if (vdev)
+		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_MCAST2UCAST);
 	qdf_nbuf_free(nbuf);
 	return 1;
 }
diff --git a/dp/wifi3.0/dp_txrx_me.h b/dp/wifi3.0/dp_txrx_me.h
index a716bdc..c801de7 100644
--- a/dp/wifi3.0/dp_txrx_me.h
+++ b/dp/wifi3.0/dp_txrx_me.h
@@ -21,15 +21,23 @@
 dp_tx_me_send_convert_ucast(struct cdp_soc_t *soc, uint8_t vdev_id,
 			    qdf_nbuf_t nbuf,
 			    uint8_t newmac[][QDF_MAC_ADDR_SIZE],
-			    uint8_t new_mac_cnt);
+			    uint8_t new_mac_cnt, uint8_t tid,
+			    bool is_igmp);
 void dp_tx_me_alloc_descriptor(struct cdp_soc_t *soc, uint8_t pdev_id);
 void dp_tx_me_free_descriptor(struct cdp_soc_t *soc, uint8_t pdev_id);
 void dp_tx_me_exit(struct dp_pdev *pdev);
 QDF_STATUS
 dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
+QDF_STATUS
+dp_tx_prepare_send_igmp_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
 extern int
 dp_me_mcast_convert(struct cdp_soc_t *soc,
 		    uint8_t vdev_id,
 		    uint8_t pdev_id,
 		    qdf_nbuf_t wbuf);
+extern int
+dp_igmp_me_mcast_convert(struct cdp_soc_t *soc,
+			 uint8_t vdev_id,
+			 uint8_t pdev_id,
+			 qdf_nbuf_t wbuf);
 #endif
diff --git a/dp/wifi3.0/dp_txrx_wds.c b/dp/wifi3.0/dp_txrx_wds.c
index 1f25910..760dfa2 100644
--- a/dp/wifi3.0/dp_txrx_wds.c
+++ b/dp/wifi3.0/dp_txrx_wds.c
@@ -228,12 +228,13 @@
  */
 #ifdef WDS_VENDOR_EXTENSION
 QDF_STATUS
-dp_txrx_set_wds_rx_policy(struct cdp_soc_t *soc, uint8_t vdev_id, u_int32_t val)
+dp_txrx_set_wds_rx_policy(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
+			  u_int32_t val)
 {
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
 	struct dp_peer *peer;
-	struct dp_vdev *vdev =
-		dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
-						    vdev_id);
+	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
+						     DP_MOD_ID_MISC);
 	if (!vdev) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 			  FL("vdev is NULL for vdev_id %d"), vdev_id);
@@ -251,6 +252,7 @@
 		dp_peer_unref_delete(peer, DP_MOD_ID_AST);
 	}
 
+	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_MISC);
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -662,8 +664,8 @@
 	 */
 	if (peer->vlan_id) {
 		dp_debug("peer already added to vdev multipass list"
-			 "MAC: "QDF_MAC_ADDR_STR" vlan: %d ",
-			 QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw), peer->vlan_id);
+			 "MAC: "QDF_MAC_ADDR_FMT" vlan: %d ",
+			 QDF_MAC_ADDR_REF(peer->mac_addr.raw), peer->vlan_id);
 		dp_peer_unref_delete(peer, DP_MOD_ID_TX_MULTIPASS);
 		return;
 	}
@@ -694,13 +696,13 @@
 {
 	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
 	struct dp_vdev *vdev =
-		dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
-						   vdev_id);
+		dp_vdev_get_ref_by_id((struct dp_soc *)soc, vdev_id,
+				      DP_MOD_ID_TX_MULTIPASS);
 
-	if (!vdev || !vdev->multipass_en)
-		return;
-
-	dp_peer_multipass_list_add(soc, peer_mac, vdev_id, vlan_id);
+	if (vdev && vdev->multipass_en) {
+		dp_peer_multipass_list_add(soc, peer_mac, vdev_id, vlan_id);
+		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_TX_MULTIPASS);
+	}
 }
 
 /**
@@ -712,15 +714,18 @@
  *
  * return: set success/failure
  */
-QDF_STATUS dp_set_vlan_groupkey(struct cdp_soc_t *soc, uint8_t vdev_id,
-		uint16_t vlan_id, uint16_t group_key)
+QDF_STATUS dp_set_vlan_groupkey(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
+				uint16_t vlan_id, uint16_t group_key)
 {
-	struct dp_vdev *vdev =
-		dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
-						    vdev_id);
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
+						     DP_MOD_ID_TX_MULTIPASS);
+	QDF_STATUS status;
 
-	if (!vdev || !vdev->multipass_en)
-		return QDF_STATUS_E_INVAL;
+	if (!vdev || !vdev->multipass_en) {
+		status = QDF_STATUS_E_INVAL;
+		goto fail;
+	}
 
 	if (!vdev->iv_vlan_map) {
 		uint16_t vlan_map_size = (sizeof(uint16_t))*DP_MAX_VLAN_IDS;
@@ -728,7 +733,8 @@
 
 		if (!vdev->iv_vlan_map) {
 			QDF_TRACE_ERROR(QDF_MODULE_ID_DP, "iv_vlan_map");
-			return QDF_STATUS_E_NOMEM;
+			status = QDF_STATUS_E_NOMEM;
+			goto fail;
 		}
 
 		/*
@@ -738,11 +744,17 @@
 		qdf_mem_zero(vdev->iv_vlan_map, vlan_map_size);
 	}
 
-	if (vlan_id >= DP_MAX_VLAN_IDS)
-		return QDF_STATUS_E_INVAL;
+	if (vlan_id >= DP_MAX_VLAN_IDS) {
+		status = QDF_STATUS_E_INVAL;
+		goto fail;
+	}
 
 	vdev->iv_vlan_map[vlan_id] = group_key;
-	return QDF_STATUS_SUCCESS;
+	status = QDF_STATUS_SUCCESS;
+fail:
+	if (vdev)
+		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_TX_MULTIPASS);
+	return status;
 }
 
 /**
diff --git a/tools/linux/cfg80211_ven_cmd.h b/tools/linux/cfg80211_ven_cmd.h
index 81978bb..a253492 100644
--- a/tools/linux/cfg80211_ven_cmd.h
+++ b/tools/linux/cfg80211_ven_cmd.h
@@ -772,6 +772,13 @@
 	IEEE80211_PARAM_RAWSIM_DEBUG_NUM_ENCAP_FRAMES   = 704, /* Sets the number of encap raw frames to dump when debug enabled */
 	IEEE80211_PARAM_RAWSIM_DEBUG_NUM_DECAP_FRAMES   = 705, /* Sets the number of decap raw frames to dump when debug enabled */
 #endif /* ATH_PERF_PWR_OFFLOAD && QCA_SUPPORT_RAWMODE_PKT_SIMULATION */
+	IEEE80211_PARAM_CURRENT_PP                 = 706, /* P Periodicity */
+	IEEE80211_PARAM_NO_ACT_VAPS                = 707, /* Active Vaps */
+	IEEE80211_PARAM_TX_VAP                     = 708, /* Current Tx Vap */
+	IEEE80211_PARAM_FILS_IS_ENABLE            = 709, /* Fils enable frames*/
+	IEEE80211_PARAM_MBSS_TXVDEV                = 710,
+	IEEE80211_PARAM_IGMP_ME      = 711, /* Set IGMP Mcast enhancement option: 0 disable, 1 enable */
+	IEEE80211_PARAM_HLOS_TID_OVERRIDE          = 712,   /* enable/disable hlos tid override support per vap */
 };
 
 enum {
@@ -1222,7 +1229,16 @@
 	OL_ATH_PARAM_PUNCTURED_BAND = 453,
 	/* Control frame configuration for MBSSID */
 	OL_ATH_PARAM_HE_MBSSID_CTRL_FRAME_CONFIG = 454,
-
+	/* Max users per-PPDU for OFDMA, 16 LSBs for DL and 16 MSBs for UL */
+	OL_ATH_PARAM_OFDMA_MAX_USERS = 455,
+	/* Max users per-PPDU for MU-MIMO, 16 LSBs for DL and 16 MSBs for UL */
+	OL_ATH_PARAM_MUMIMO_MAX_USERS = 456,
+	/* ACS pre-CAC only channel selection support */
+	OL_ATH_PARAM_ACS_PRECAC_SUPPORT = 457,
+	/* MBSSID AUTO MODE TX VDEV derivation */
+	OL_ATH_PARAM_MBSS_AUTOMODE = 458,
+	/* RNR selective addition */
+	OL_ATH_PARAM_RNR_SELECTIVE_ADD = 459,
 };
 
 #ifdef CONFIG_SUPPORT_LIBROXML
@@ -2190,6 +2206,8 @@
 #endif
 	{"mscs",                IEEE80211_PARAM_ENABLE_MSCS, SET_PARAM, 1},
 	{"g_mscs",              IEEE80211_PARAM_ENABLE_MSCS, GET_PARAM, 0},
+	{"mbss_tx_vdev",        IEEE80211_PARAM_MBSS_TXVDEV, SET_PARAM, 1},
+	{"g_mbss_tx_vdev",      IEEE80211_PARAM_MBSS_TXVDEV, GET_PARAM, 0},
 	{"setiebuf",            35828, SET_PARAM, 1},
 	{"getiebuf",            35827, GET_PARAM, 0},
 	{"dbgreq",              35832, SET_PARAM, 1},
@@ -2199,6 +2217,10 @@
 	{"rxtimeout",           35839, SET_PARAM, 1},
 	{"oce_version_override ",     IEEE80211_PARAM_OCE_VERSION_OVERRIDE, SET_PARAM, 1},
 	{"g_oce_version_override ",   IEEE80211_PARAM_OCE_VERSION_OVERRIDE, GET_PARAM, 0},
+	{"igmpmcasten",         IEEE80211_PARAM_IGMP_ME, SET_PARAM, 1},
+	{"g_igmpmcasten",       IEEE80211_PARAM_IGMP_ME, GET_PARAM, 0},
+	{"hlos_tidoverride ",     IEEE80211_PARAM_HLOS_TID_OVERRIDE, SET_PARAM, 1},
+	{"g_hlos_tidoverride ",     IEEE80211_PARAM_HLOS_TID_OVERRIDE, GET_PARAM, 0},
 };
 
 struct vendor_commands radio_vendor_cmds[] = {
@@ -3122,9 +3144,9 @@
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_NO_BACKHAUL_RADIO, SET_PARAM, 1},
 	{"g_nobckhlradio",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_NO_BACKHAUL_RADIO, GET_PARAM, 0},
-	{"enable_additional_triplets",
+	{"set_triplets_bw",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_ENABLE_ADDITIONAL_TRIPLETS, SET_PARAM, 1},
-	{"g_enable_additional_triplets",
+	{"get_triplets_bw",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_ENABLE_ADDITIONAL_TRIPLETS, GET_PARAM, 0},
 #ifdef QCA_SUPPORT_DFS_CHAN_POSTNOL
 	{"setpostNOLfreq",
@@ -3156,6 +3178,24 @@
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_HE_MBSSID_CTRL_FRAME_CONFIG, SET_PARAM, 1},
 	{"g_he_mbssid_ctrl_frame_config",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_HE_MBSSID_CTRL_FRAME_CONFIG, GET_PARAM, 0},
+	{"get_ofdma_usr",
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_OFDMA_MAX_USERS, GET_PARAM, 0},
+	{"get_mumimo_usr",
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_MUMIMO_MAX_USERS, GET_PARAM, 0},
+	{"acs_pcaconly",
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_ACS_PRECAC_SUPPORT, SET_PARAM, 1},
+	{"g_acs_pcaconly",
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_ACS_PRECAC_SUPPORT, GET_PARAM, 0},
+	{"mbss_auto",
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_MBSS_AUTOMODE, SET_PARAM, 1},
+	{"g_mbss_auto",
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_MBSS_AUTOMODE, GET_PARAM, 0},
+	{"selective_rnr_nontx",
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_RNR_SELECTIVE_ADD,
+		SET_PARAM, 1},
+	{"g_selective_rnr_nontx",
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_RNR_SELECTIVE_ADD,
+		GET_PARAM, 0},
 };
 #endif
 #endif
diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_defs.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_defs.h
index 6df73b2..10c5b3b 100644
--- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_defs.h
+++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_defs.h
@@ -297,6 +297,9 @@
  * @peer_delete_resp: no of peer delete resp rcvd from target
  * @peer_delete_all_req: no of peer delete all req sent to target
  * @peer_delete_all_resp: no of peer delete all resp rcvd from target
+ * @prob_req_drops: no of probe requests drops
+ * @oob_probe_req_count: no of out of band probe requests
+ * @wc_probe_req_drops: no of wildcard probe requests drops
  */
 struct vdev_80211_stats {
 	uint64_t cs_rx_wrongbss;
@@ -366,6 +369,11 @@
 	uint64_t cs_peer_delete_resp;
 	uint64_t cs_peer_delete_all_req;
 	uint64_t cs_peer_delete_all_resp;
+	uint64_t cs_prob_req_drops;
+	uint64_t cs_oob_probe_req_count;
+	uint64_t cs_wc_probe_req_drops;
+	uint64_t cs_fils_frames_sent;
+	uint64_t cs_fils_frames_sent_fail;
 };
 
 /**
diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_ucfg_api.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_ucfg_api.h
index 270a7e3..d62aed1 100644
--- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_ucfg_api.h
+++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_ucfg_api.h
@@ -380,6 +380,11 @@
 UCFG_VDEV_CP_STATS_SET_FUNCS(peer_delete_resp);
 UCFG_VDEV_CP_STATS_SET_FUNCS(peer_delete_all_req);
 UCFG_VDEV_CP_STATS_SET_FUNCS(peer_delete_all_resp);
+UCFG_VDEV_CP_STATS_SET_FUNCS(prob_req_drops);
+UCFG_VDEV_CP_STATS_SET_FUNCS(oob_probe_req_count);
+UCFG_VDEV_CP_STATS_SET_FUNCS(wc_probe_req_drops);
+UCFG_VDEV_CP_STATS_SET_FUNCS(fils_frames_sent);
+UCFG_VDEV_CP_STATS_SET_FUNCS(fils_frames_sent_fail);
 
 #define UCFG_VDEV_CP_STATS_GET_FUNCS(field) \
 	static inline uint64_t \
diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_utils_api.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_utils_api.h
index 0ab1f64..18bf795 100644
--- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_utils_api.h
+++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_utils_api.h
@@ -274,6 +274,11 @@
 VDEV_CP_STATS_SET_FUNCS(peer_delete_resp);
 VDEV_CP_STATS_SET_FUNCS(peer_delete_all_req);
 VDEV_CP_STATS_SET_FUNCS(peer_delete_all_resp);
+VDEV_CP_STATS_SET_FUNCS(prob_req_drops);
+VDEV_CP_STATS_SET_FUNCS(oob_probe_req_count);
+VDEV_CP_STATS_SET_FUNCS(wc_probe_req_drops);
+VDEV_CP_STATS_SET_FUNCS(fils_frames_sent);
+VDEV_CP_STATS_SET_FUNCS(fils_frames_sent_fail);
 
 #define VDEV_CP_STATS_GET_FUNCS(field) \
 	static inline uint64_t \
diff --git a/umac/dfs/core/src/misc/dfs_zero_cac.c b/umac/dfs/core/src/misc/dfs_zero_cac.c
index 6a4ae96..3192af4 100644
--- a/umac/dfs/core/src/misc/dfs_zero_cac.c
+++ b/umac/dfs/core/src/misc/dfs_zero_cac.c
@@ -1894,6 +1894,8 @@
 	precac_entry->center_ch_ieee =
 	utils_dfs_freq_to_chan(precac_center_freq);
 	precac_entry->bw = dfs_max_bw_info[index].dfs_max_bw;
+	/* non_dfs_subch_count will be updated once the channels are marked. */
+	precac_entry->non_dfs_subch_count = 0;
 	precac_entry->dfs = dfs;
 	status =
 	    dfs_create_precac_tree_for_freq(dfs,
@@ -1921,6 +1923,8 @@
 	precac_entry->center_ch_ieee =
 		utils_dfs_freq_to_chan(precac_entry->center_ch_freq);
 	precac_entry->bw = DFS_CHWIDTH_160_VAL;
+	/* non_dfs_subch_count will be updated once the channels are marked. */
+	precac_entry->non_dfs_subch_count = 0;
 	precac_entry->dfs = dfs;
 	dfs_insert_node_into_bstree_for_freq(&precac_entry->tree_root,
 					     RESTRICTED_80P80_CHAN_CENTER_FREQ,
@@ -1945,6 +1949,35 @@
 	return status;
 }
 
+/**
+ * dfs_update_non_dfs_subchannel_count() - API to update the preCAC entry
+ * with the given non DFS subchannel count.
+ * @dfs:       Pointer to DFS object.
+ * @frequency: Frequency whose corresponding preCAC entry needs to be updated.
+ * @count:     Non DFS subchannel count for the preCAC entry.
+ */
+static void
+dfs_update_non_dfs_subchannel_count(struct wlan_dfs *dfs,
+				    qdf_freq_t frequency,
+				    uint8_t count)
+{
+	struct dfs_precac_entry *precac_entry = NULL, *tmp_precac_entry = NULL;
+
+	PRECAC_LIST_LOCK(dfs);
+	TAILQ_FOREACH_SAFE(precac_entry,
+			   &dfs->dfs_precac_list,
+			   pe_list,
+			   tmp_precac_entry) {
+		if (IS_WITHIN_RANGE_STRICT(frequency,
+					   precac_entry->center_ch_freq,
+					   (precac_entry->bw/2))) {
+			precac_entry->non_dfs_subch_count = count;
+			break;
+		}
+	}
+	PRECAC_LIST_UNLOCK(dfs);
+}
+
 static void
 dfs_mark_non_dfs_as_precac_done(struct wlan_dfs *dfs,
 				uint16_t dfs_pri_ch_freq,
@@ -1971,6 +2004,9 @@
 					      ichan->dfs_ch_mhz_freq_seg1,
 					      0,
 					      CH_WIDTH_80MHZ);
+		dfs_update_non_dfs_subchannel_count(dfs,
+						    ichan->dfs_ch_mhz_freq_seg1,
+						    N_SUBCHANS_FOR_80BW);
 		PRECAC_LIST_LOCK(dfs);
 	} else if (!WLAN_IS_CHAN_DFS_CFREQ2(ichan)) {
 		PRECAC_LIST_UNLOCK(dfs);
@@ -1978,6 +2014,9 @@
 					      ichan->dfs_ch_mhz_freq_seg2,
 					      0,
 					      CH_WIDTH_80MHZ);
+		dfs_update_non_dfs_subchannel_count(dfs,
+						    ichan->dfs_ch_mhz_freq_seg2,
+						    N_SUBCHANS_FOR_80BW);
 		PRECAC_LIST_LOCK(dfs);
 	}
 }
@@ -2919,6 +2958,56 @@
 	}
 }
 
+/**
+ * dfs_is_precac_completed_count_non_zero() - API to find if the preCAC
+ * completed channels count is zero/non_zero.
+ * @dfs: Pointer to DFS object.
+ *
+ * Return true, if there exists atleast one node/subchannel in the preCAC list
+ * that is CAC done, else return false.
+ */
+static bool
+dfs_is_precac_completed_count_non_zero(struct wlan_dfs *dfs)
+{
+	struct dfs_precac_entry *precac_entry = NULL;
+
+	PRECAC_LIST_LOCK(dfs);
+	if (!TAILQ_EMPTY(&dfs->dfs_precac_list)) {
+		TAILQ_FOREACH(precac_entry,
+			      &dfs->dfs_precac_list,
+			      pe_list) {
+			/* Find if the tree root has any preCAC channels
+			 * that is CAC done.
+			 */
+			if (!precac_entry->tree_root->n_caced_subchs)
+				continue;
+			if (abs(precac_entry->tree_root->n_caced_subchs -
+			    precac_entry->non_dfs_subch_count)) {
+				PRECAC_LIST_UNLOCK(dfs);
+				return true;
+			}
+		}
+	}
+	PRECAC_LIST_UNLOCK(dfs);
+
+	return false;
+}
+
+#ifdef ATH_SUPPORT_ZERO_CAC_DFS
+enum precac_status_for_chan
+dfs_precac_status_for_channel(struct wlan_dfs *dfs,
+			      struct dfs_channel *deschan)
+{
+	if (!dfs_is_precac_completed_count_non_zero(dfs))
+		return DFS_NO_PRECAC_COMPLETED_CHANS;
+
+	if (dfs_is_precac_done(dfs, deschan))
+		return DFS_PRECAC_COMPLETED_CHAN;
+
+	return DFS_PRECAC_REQUIRED_CHAN;
+}
+#endif
+
 void dfs_print_precaclists(struct wlan_dfs *dfs)
 {
 	struct dfs_precac_entry *tmp_precac_entry;
diff --git a/umac/mlme/conn_mgr/core/src/wlan_cm_blm_main.c b/umac/mlme/conn_mgr/core/src/wlan_cm_blm_main.c
new file mode 100644
index 0000000..5d0738f
--- /dev/null
+++ b/umac/mlme/conn_mgr/core/src/wlan_cm_blm_main.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: Implement APIs related to the Blacklist manager
+ */
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_scan_utils_api.h>
+#include <wlan_cm_bss_score_param.h>
+#include <wlan_cm_blm.h>
+#include "wlan_cm_blm_main.h"
+
+static void blm_filter_vdev_mac_cmp(struct wlan_objmgr_pdev *pdev,
+				    void *obj, void *args)
+{
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj;
+	struct blm_entry_iter_obj *blm_obj = (struct blm_entry_iter_obj *)args;
+	uint8_t *scan_entry_mac;
+
+	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)
+		blm_obj->sta_vdev = vdev;
+
+	if (blm_obj->match)
+		return;
+
+	scan_entry_mac = util_scan_entry_macaddr(blm_obj->db_entry);
+	if (qdf_mem_cmp(scan_entry_mac,
+			wlan_vdev_mlme_get_macaddr(vdev),
+			QDF_MAC_ADDR_SIZE) == 0) {
+		blm_obj->match = true;
+	}
+}
+
+enum cm_blacklist_action
+wlan_blacklist_action_on_bssid(struct wlan_objmgr_pdev *pdev,
+			       struct scan_cache_entry *entry)
+{
+	struct blm_entry_iter_obj blm_iter_obj = {0};
+	uint8_t (*exc_mac_list)[QDF_MAC_ADDR_SIZE] = NULL;
+	uint8_t *scan_entry_mac;
+	struct wlan_objmgr_vdev *sta_vdev;
+	enum cm_blm_exc_mac_mode exc_mac_status;
+	uint8_t num_exc_mac = 0;
+	qdf_time_t bad_ap_timeout = 0;
+	qdf_time_t time_diff = 0;
+	uint8_t idx;
+
+	/*
+	 * Avoid scan entry with bssid matching any of the vdev mac
+	 */
+	blm_iter_obj.db_entry = entry;
+	blm_iter_obj.match = false;
+
+	wlan_objmgr_pdev_iterate_obj_list(
+			pdev, WLAN_VDEV_OP,
+			blm_filter_vdev_mac_cmp,
+			&blm_iter_obj, 0, WLAN_SCAN_ID);
+
+	if (blm_iter_obj.match) {
+		qdf_info("Ignore entry %pM match vdev mac", entry->bssid.bytes);
+		return CM_BLM_REMOVE;
+	}
+
+	if (!blm_iter_obj.sta_vdev)
+		return CM_BLM_NO_ACTION;
+
+	sta_vdev = blm_iter_obj.sta_vdev;
+
+	/*
+	 * Skip scan entry that is marked as BAD AP
+	 */
+	bad_ap_timeout  = wlan_cm_get_bad_ap_timeout(sta_vdev);
+	if (wlan_cm_blm_scan_mlme_get_status(entry) & AP_STATE_BAD) {
+		time_diff  = qdf_system_ticks() -
+			wlan_cm_blm_scan_mlme_get_bad_ap_time(entry);
+		if (!bad_ap_timeout ||
+		    (qdf_system_ticks_to_msecs(time_diff) > bad_ap_timeout)) {
+			wlan_cm_blm_scan_mlme_set_bad_ap_time(entry, 0);
+			wlan_cm_blm_scan_mlme_set_status(entry,
+							 AP_STATE_GOOD);
+		} else {
+			qdf_info("Ignore bssid entry %pM", entry->bssid.bytes);
+			return CM_BLM_REMOVE;
+		}
+	}
+
+	/*
+	 * Skip scan entries in the excluded mac address list
+	 */
+	exc_mac_status = wlan_cm_get_exc_mac_addr_list(sta_vdev,
+						       &exc_mac_list,
+						       &num_exc_mac);
+	if (exc_mac_status == CM_BLM_EXC_MAC_ALL) {
+		qdf_info("Ignore bssid entry %pM", entry->bssid.bytes);
+		return CM_BLM_REMOVE;
+	} else if (exc_mac_status == CM_BLM_EXC_MAC_NONE) {
+		return CM_BLM_NO_ACTION;
+	}
+
+	scan_entry_mac = util_scan_entry_macaddr(entry);
+	for (idx = 0; idx < num_exc_mac; idx++) {
+		if (qdf_mem_cmp(scan_entry_mac,
+				exc_mac_list[idx],
+				QDF_MAC_ADDR_SIZE) == 0) {
+			qdf_info("Ignore bssid entry %pM", entry->bssid.bytes);
+			return CM_BLM_REMOVE;
+		}
+	}
+
+	return CM_BLM_NO_ACTION;
+}
diff --git a/umac/mlme/conn_mgr/core/src/wlan_cm_blm_main.h b/umac/mlme/conn_mgr/core/src/wlan_cm_blm_main.h
new file mode 100644
index 0000000..3fa3138
--- /dev/null
+++ b/umac/mlme/conn_mgr/core/src/wlan_cm_blm_main.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2020 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: Define APIs related to the Blacklist manager
+ */
+
+#ifndef _WLAN_CM_BLM_MAIN_H_
+#define _WLAN_CM_BLM_MAIN_H_
+#include <wlan_scan_public_structs.h>
+
+/**
+ * blm_entry_iter_obj - Object of blm iter function
+ * @db_entry: scan entry object
+ * @sta_vdev: station's vdev object
+ * @match: Hold the operation result
+ */
+struct blm_entry_iter_obj {
+	struct scan_cache_entry *db_entry;
+	struct wlan_objmgr_vdev *sta_vdev;
+	bool match;
+};
+#endif
diff --git a/umac/mlme/conn_mgr/dispatcher/inc/wlan_cm_blm.h b/umac/mlme/conn_mgr/dispatcher/inc/wlan_cm_blm.h
new file mode 100644
index 0000000..22a9eac
--- /dev/null
+++ b/umac/mlme/conn_mgr/dispatcher/inc/wlan_cm_blm.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2020 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: Define APIs related to the Blacklist manager
+ */
+
+#ifndef _WLAN_CM_BLM_H_
+#define _WLAN_CM_BLM_H_
+#include <wlan_scan_utils_api.h>
+
+/*
+ * Flags used to set field APState
+ */
+#define AP_STATE_GOOD    0x00
+#define AP_STATE_BAD     0x01
+#define AP_STATE_RETRY   0x10
+
+
+/**
+ * enum cm_blm_exc_mac_mode - Exclude mac list mode
+ * @CM_BLM_EXC_MAC_NONE - No entries in exclude mac list
+ * @CM_BLM_EXC_MAC_FEW - Entries available in exclude mac list
+ * @CM_BLM_EXC_MAC_ALL - Ignore all the mac
+ */
+enum cm_blm_exc_mac_mode {
+	CM_BLM_EXC_MAC_NONE,
+	CM_BLM_EXC_MAC_FEW,
+	CM_BLM_EXC_MAC_ALL,
+};
+
+static inline uint32_t
+wlan_cm_blm_scan_mlme_get_status(struct scan_cache_entry *scan_entry)
+{
+    return util_scan_entry_mlme_info(scan_entry)->status;
+}
+
+static inline void
+wlan_cm_blm_scan_mlme_set_status(struct scan_cache_entry *scan_entry, uint32_t val)
+{
+    util_scan_entry_mlme_info(scan_entry)->status = val;
+}
+
+static inline qdf_time_t
+wlan_cm_blm_scan_mlme_get_bad_ap_time(struct scan_cache_entry *scan_entry)
+{
+	return util_scan_entry_mlme_info(scan_entry)->bad_ap_time;
+}
+
+static inline void
+wlan_cm_blm_scan_mlme_set_bad_ap_time(struct scan_cache_entry *scan_entry, qdf_time_t val)
+{
+	util_scan_entry_mlme_info(scan_entry)->bad_ap_time = val;
+}
+
+/*
+ * wlan_cm_get_exc_mac_addr_list: Get excluded mac address list
+ * @vdev: vdev object
+ * @exc_mac_list: Pointer to the excluded mac address list
+ * @exc_mac_count: Number of entries in the excluded list
+ *
+ * Return: Status of the excluded mac addresses
+ */
+enum cm_blm_exc_mac_mode wlan_cm_get_exc_mac_addr_list(
+		struct wlan_objmgr_vdev *vdev,
+		uint8_t (**exc_mac_list)[QDF_MAC_ADDR_SIZE],
+		uint8_t *exc_mac_count);
+
+/*
+ * wlan_cm_get_bad_ap_timeout: Get bad ap timeout duration
+ * @vdev: vdev object
+ *
+ * Return: Congfigured bad ap timeout value
+ */
+qdf_time_t wlan_cm_get_bad_ap_timeout(struct wlan_objmgr_vdev *vdev);
+#endif
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 5163ce5..e3fc6b1 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
@@ -189,6 +189,23 @@
 	return status;
 }
 
+static void wlan_vdev_start_fw_send(struct wlan_objmgr_pdev *pdev,
+				    void *object,
+				    void *arg)
+{
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
+	unsigned long *send_array = (unsigned long *)arg;
+
+	if (wlan_util_map_index_is_set(send_array, wlan_vdev_get_id(vdev)) ==
+					false)
+		return;
+
+	mlme_vdev_start_fw_cmd_send(pdev, vdev, 0);
+
+	 /* Reset the flag */
+	wlan_util_change_map_index(send_array, wlan_vdev_get_id(vdev), 0);
+}
+
 static QDF_STATUS mlme_stop_pending_restart(struct wlan_objmgr_pdev *pdev,
 					    struct wlan_objmgr_vdev *vdev)
 {
@@ -227,7 +244,18 @@
 					 WLAN_PDEV_OP_RESTART_INPROGRESS);
 			wlan_pdev_mlme_op_clear(pdev,
 						WLAN_PDEV_OP_MBSSID_RESTART);
+
+			if (wlan_util_map_is_any_index_set(
+			    pdev_mlme->start_send_vdev_arr,
+			    sizeof(pdev_mlme->start_send_vdev_arr))) {
+				wlan_objmgr_pdev_iterate_obj_list(
+					 pdev, WLAN_VDEV_OP,
+					 wlan_vdev_start_fw_send,
+					 pdev_mlme->start_send_vdev_arr, 0,
+					 WLAN_MLME_NB_ID);
+			}
 		}
+
 	}
 	qdf_spin_unlock_bh(&pdev_mlme->vdev_restart_lock);
 
@@ -250,23 +278,6 @@
 	wlan_util_change_map_index(send_array, wlan_vdev_get_id(vdev), 0);
 }
 
-static void wlan_vdev_start_fw_send(struct wlan_objmgr_pdev *pdev,
-				    void *object,
-				    void *arg)
-{
-	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
-	unsigned long *send_array = (unsigned long *)arg;
-
-	if (wlan_util_map_index_is_set(send_array, wlan_vdev_get_id(vdev)) ==
-					false)
-		return;
-
-	mlme_vdev_start_fw_cmd_send(pdev, vdev, 0);
-
-	 /* Reset the flag */
-	wlan_util_change_map_index(send_array, wlan_vdev_get_id(vdev), 0);
-}
-
 static void wlan_vdev_update_des_chan(struct wlan_objmgr_pdev *pdev,
 				      void *object,
 				      void *arg)
diff --git a/umac/rnr/inc/wlan_rnr.h b/umac/rnr/inc/wlan_rnr.h
new file mode 100644
index 0000000..e306774
--- /dev/null
+++ b/umac/rnr/inc/wlan_rnr.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#ifndef _WLAN_RNR_H_
+#define _WLAN_RNR_H_
+#include <qdf_atomic.h>
+#include <wlan_objmgr_pdev_obj.h>
+
+/**
+ * struct rnr_global_info - Global context for RNR
+ * @vdev_lower_band_cnt:    5ghz/2ghz vdev count
+ * @vdev_6ghz_band_cnt:     6ghz vdev count
+ * @pdev_6ghz_ctx:          6Ghz pdev context
+ */
+struct rnr_global_info {
+	qdf_atomic_t vdev_lower_band_cnt;
+	qdf_atomic_t vdev_6ghz_band_cnt;
+	uint32_t rnr_mbss_idx_map;
+	struct wlan_objmgr_pdev *pdev_6ghz_ctx;
+};
+
+/**
+ * wlan_rnr_lower_band_vdev_inc - Atomic increment of
+ *				  global lower band vdev counter
+ *
+ * API to increment global lower band vdev counter
+ *
+ * Return:void
+ */
+void wlan_rnr_lower_band_vdev_inc(void);
+
+/**
+ * wlan_rnr_lower_band_vdev_dec - Atomic decrement of
+ *				  global lower band vdev counter
+ *
+ * API to decrement global lower band vdev counter
+ *
+ * Return:void
+ */
+void wlan_rnr_lower_band_vdev_dec(void);
+
+/**
+ * wlan_rnr_6ghz_vdev_inc - Atomic increment of
+ *			    6ghz vdev counter
+ *
+ * API to increment of 6Ghz vdev counter
+ *
+ * Return:void
+ */
+void wlan_rnr_6ghz_vdev_inc(void);
+
+/**
+ * wlan_rnr_6ghz_vdev_dec - Atomic decrement of
+ *			    6ghz vdev counter
+ *
+ * API to decrement of 6Ghz vdev counter
+ *
+ * Return:void
+ */
+void wlan_rnr_6ghz_vdev_dec(void);
+
+/**
+ * wlan_global_6ghz_pdev_set - Store 6Ghz pdev in
+ *			       global context
+ *
+ * API to save 6Ghz pdev in global context for
+ * faster access
+ *
+ * Return:void
+ */
+void wlan_global_6ghz_pdev_set(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * wlan_global_6ghz_pdev_destroy - Delete 6Ghz pdev in
+ *				   global context
+ *
+ * API to delete 6Ghz pdev in global context for
+ * faster access
+ *
+ * Return:void
+ */
+void wlan_global_6ghz_pdev_destroy(void);
+
+/**
+ * wlan_lower_band_ap_cnt_get - Get lower band AP count
+ *
+ * API to get lower band vdev from global context for
+ * faster access
+ *
+ * Return: int32_t
+ */
+int32_t wlan_lower_band_ap_cnt_get(void);
+
+/**
+ * wlan_rnr_init_cnt - Initialize counters for
+ *			6Ghz vdev and lower band vdev
+ *
+ * API to initialize atomic counters used for 6Ghz vdev
+ * and lower band vdev
+ *
+ * Return: void
+ */
+void wlan_rnr_init_cnt(void);
+
+/**
+ * wlan_gbl_6ghz_pdev_get - Retrieve 6Ghz pdev pointer
+ *
+ * API to get 6Ghz pdev pointer
+ *
+ * Return: struct wlan_objmgr_pdev
+ */
+struct wlan_objmgr_pdev *wlan_gbl_6ghz_pdev_get(void);
+
+/**
+ * wlan_rnr_set_bss_idx - Set bit corresponding to bss index
+ *
+ * API to set bss index bitmap for adding Non Tx APs
+ * not included in Mbss IE in the RNR IE
+ *
+ * Return: void
+ */
+void wlan_rnr_set_bss_idx(uint32_t bss_idx);
+
+/**
+ * wlan_rnr_get_bss_idx - Get bit corresponding to bss index
+ *
+ * API to Get bss index bitmap for adding Non Tx APs
+ * not included in Mbss IE in the RNR IE
+ *
+ * Return: void
+ */
+uint32_t wlan_rnr_get_bss_idx(void);
+
+/**
+ * wlan_rnr_clear_bss_idx - Clear bits corresponding to bss index map
+ *
+ * API to clear bss index bitmap for adding Non Tx APs
+ * not included in Mbss IE in the RNR IE
+ *
+ * Return: void
+ */
+void wlan_rnr_clear_bss_idx(void);
+
+#endif /* End of _WLAN_RNR_H_ */
diff --git a/umac/rnr/src/wlan_rnr.c b/umac/rnr/src/wlan_rnr.c
new file mode 100644
index 0000000..bfc9ee5
--- /dev/null
+++ b/umac/rnr/src/wlan_rnr.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2020 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 <wlan_rnr.h>
+#include <qdf_module.h>
+#include <qdf_status.h>
+#include <qdf_types.h>
+
+struct rnr_global_info g_rnr_info;
+
+void wlan_rnr_init_cnt(void)
+{
+	qdf_atomic_init(&(g_rnr_info.vdev_lower_band_cnt));
+	qdf_atomic_init(&(g_rnr_info.vdev_6ghz_band_cnt));
+}
+
+qdf_export_symbol(wlan_rnr_init_cnt);
+
+void wlan_rnr_lower_band_vdev_inc(void)
+{
+	qdf_atomic_inc(&(g_rnr_info.vdev_lower_band_cnt));
+}
+
+qdf_export_symbol(wlan_rnr_lower_band_vdev_inc);
+
+void wlan_rnr_lower_band_vdev_dec(void)
+{
+	qdf_atomic_dec(&(g_rnr_info.vdev_lower_band_cnt));
+}
+
+qdf_export_symbol(wlan_rnr_lower_band_vdev_dec);
+
+void wlan_rnr_6ghz_vdev_inc(void)
+{
+	qdf_atomic_inc(&(g_rnr_info.vdev_6ghz_band_cnt));
+}
+
+qdf_export_symbol(wlan_rnr_6ghz_vdev_inc);
+
+void wlan_rnr_6ghz_vdev_dec(void)
+{
+	qdf_atomic_dec(&(g_rnr_info.vdev_6ghz_band_cnt));
+}
+
+qdf_export_symbol(wlan_rnr_6ghz_vdev_dec);
+
+void wlan_global_6ghz_pdev_set(struct wlan_objmgr_pdev *pdev)
+{
+	if (pdev)
+		g_rnr_info.pdev_6ghz_ctx = pdev;
+}
+
+qdf_export_symbol(wlan_global_6ghz_pdev_set);
+
+void wlan_global_6ghz_pdev_destroy(void)
+{
+	g_rnr_info.pdev_6ghz_ctx = NULL;
+}
+
+qdf_export_symbol(wlan_global_6ghz_pdev_destroy);
+
+int32_t wlan_lower_band_ap_cnt_get(void)
+{
+	return qdf_atomic_read(&(g_rnr_info.vdev_lower_band_cnt));
+}
+
+qdf_export_symbol(wlan_lower_band_ap_cnt_get);
+
+struct wlan_objmgr_pdev *wlan_gbl_6ghz_pdev_get(void)
+{
+	return g_rnr_info.pdev_6ghz_ctx;
+}
+
+qdf_export_symbol(wlan_gbl_6ghz_pdev_get);
+
+void wlan_rnr_set_bss_idx(uint32_t bss_idx)
+{
+	g_rnr_info.rnr_mbss_idx_map |= (1 << (bss_idx-1));
+}
+
+uint32_t wlan_rnr_get_bss_idx(void)
+{
+	return g_rnr_info.rnr_mbss_idx_map;
+}
+
+void  wlan_rnr_clear_bss_idx(void)
+{
+	g_rnr_info.rnr_mbss_idx_map = 0;
+}
diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c
index d2dc84b..38d720e 100644
--- a/wmi/src/wmi_unified_non_tlv.c
+++ b/wmi/src/wmi_unified_non_tlv.c
@@ -3102,6 +3102,7 @@
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef WMI_SMART_ANT_SUPPORT
 /**
  *  send_smart_ant_enable_cmd_non_tlv() - WMI smart ant enable function
  *
@@ -3437,6 +3438,44 @@
 }
 
 /**
+ * send_set_ant_switch_tbl_cmd_non_tlv() - send ant switch tbl cmd to fw
+ * @wmi_handle: wmi handle
+ * @param: pointer to hold ant switch tbl param
+ *
+ * Return: 0 for success or error code
+ */
+static QDF_STATUS
+send_set_ant_switch_tbl_cmd_non_tlv(wmi_unified_t wmi_handle,
+				struct ant_switch_tbl_params *param)
+{
+	uint8_t len;
+	wmi_buf_t buf;
+	wmi_pdev_set_ant_switch_tbl_cmd *cmd;
+
+	len = sizeof(wmi_pdev_set_ant_switch_tbl_cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+	cmd = (wmi_pdev_set_ant_switch_tbl_cmd *)wmi_buf_data(buf);
+	cmd->antCtrlCommon1 = param->ant_ctrl_common1;
+	cmd->antCtrlCommon2 = param->ant_ctrl_common2;
+
+	if (wmi_unified_cmd_send(wmi_handle, buf, len,
+		WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) {
+		WMI_LOGE("Failed to send WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID");
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
+#endif
+
+/**
  * send_vdev_spectral_configure_cmd_non_tlv() - send VDEV spectral configure
  * command to fw
  * @wmi_handle: wmi handle
@@ -4781,41 +4820,6 @@
 }
 
 /**
- * send_set_ant_switch_tbl_cmd_non_tlv() - send ant switch tbl cmd to fw
- * @wmi_handle: wmi handle
- * @param: pointer to hold ant switch tbl param
- *
- * Return: 0 for success or error code
- */
-static QDF_STATUS
-send_set_ant_switch_tbl_cmd_non_tlv(wmi_unified_t wmi_handle,
-				struct ant_switch_tbl_params *param)
-{
-	uint8_t len;
-	wmi_buf_t buf;
-	wmi_pdev_set_ant_switch_tbl_cmd *cmd;
-
-	len = sizeof(wmi_pdev_set_ant_switch_tbl_cmd);
-	buf = wmi_buf_alloc(wmi_handle, len);
-	if (!buf) {
-		WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
-		return QDF_STATUS_E_NOMEM;
-	}
-	cmd = (wmi_pdev_set_ant_switch_tbl_cmd *)wmi_buf_data(buf);
-	cmd->antCtrlCommon1 = param->ant_ctrl_common1;
-	cmd->antCtrlCommon2 = param->ant_ctrl_common2;
-
-	if (wmi_unified_cmd_send(wmi_handle, buf, len,
-		WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) {
-		WMI_LOGE("Failed to send WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID");
-		wmi_buf_free(buf);
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	return QDF_STATUS_SUCCESS;
-}
-
-/**
  * send_set_ratepwr_table_cmd_non_tlv() - send rate power table cmd to fw
  * @wmi_handle: wmi handle
  * @param: pointer to hold rate power table param
@@ -10271,7 +10275,18 @@
 	.send_set_ht_ie_cmd = send_set_ht_ie_cmd_non_tlv,
 	.send_set_vht_ie_cmd = send_set_vht_ie_cmd_non_tlv,
 	.send_wmm_update_cmd = send_wmm_update_cmd_non_tlv,
+#ifdef WMI_SMART_ANT_SUPPORT
 	.send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_non_tlv,
+	.send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_non_tlv,
+	.send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_non_tlv,
+	.send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_non_tlv,
+	.send_smart_ant_set_training_info_cmd =
+			send_smart_ant_set_training_info_cmd_non_tlv,
+	.send_smart_ant_set_node_config_cmd =
+			send_smart_ant_set_node_config_cmd_non_tlv,
+	.send_smart_ant_enable_tx_feedback_cmd =
+			send_smart_ant_enable_tx_feedback_cmd_non_tlv,
+#endif
 	.send_set_ratepwr_table_cmd = send_set_ratepwr_table_cmd_non_tlv,
 	.send_get_ratepwr_table_cmd = send_get_ratepwr_table_cmd_non_tlv,
 	.send_set_ctl_table_cmd = send_set_ctl_table_cmd_non_tlv,
@@ -10292,15 +10307,6 @@
 				send_peer_update_wds_entry_cmd_non_tlv,
 	.send_phyerr_enable_cmd = send_phyerr_enable_cmd_non_tlv,
 	.send_phyerr_disable_cmd = send_phyerr_disable_cmd_non_tlv,
-	.send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_non_tlv,
-	.send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_non_tlv,
-	.send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_non_tlv,
-	.send_smart_ant_set_training_info_cmd =
-			send_smart_ant_set_training_info_cmd_non_tlv,
-	.send_smart_ant_set_node_config_cmd =
-			send_smart_ant_set_node_config_cmd_non_tlv,
-	.send_smart_ant_enable_tx_feedback_cmd =
-			send_smart_ant_enable_tx_feedback_cmd_non_tlv,
 	.send_vdev_spectral_configure_cmd =
 			send_vdev_spectral_configure_cmd_non_tlv,
 	.send_vdev_spectral_enable_cmd =
diff --git a/wmi/src/wmi_unified_smart_ant_tlv.c b/wmi/src/wmi_unified_smart_ant_tlv.c
index 7987caf..a6a8c01 100644
--- a/wmi/src/wmi_unified_smart_ant_tlv.c
+++ b/wmi/src/wmi_unified_smart_ant_tlv.c
@@ -22,7 +22,7 @@
 #include "wmi_unified_smart_ant_param.h"
 #include "wmi_unified_smart_ant_api.h"
 
-#ifdef UNIFIED_SMARTANTENNA
+#ifdef WMI_SMART_ANT_SUPPORT
 /**
  *  send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function
  *