Merge changes  into win_wlan_host.1.0
diff --git a/configs/wlan_cfg/ap_wlan_cfg.config b/configs/wlan_cfg/ap_wlan_cfg.config
index 525791c..dd0ffb8 100644
--- a/configs/wlan_cfg/ap_wlan_cfg.config
+++ b/configs/wlan_cfg/ap_wlan_cfg.config
@@ -34,3 +34,6 @@
 EXTRA_CFLAGS += -DRX_DATA_BUFFER_SIZE=1792
 EXTRA_CFLAGS += -DRX_DATA_BUFFER_ALIGNMENT=0
 endif
+
+EXTRA_CFLAGS += -DWLAN_PSOC_MAX_VDEVS=60
+EXTRA_CFLAGS += -DWLAN_PDEV_MAX_VDEVS=30
diff --git a/dp/wifi3.0/dp_rx_mon_feature.c b/dp/wifi3.0/dp_rx_mon_feature.c
index 121714e..4a4c66b 100644
--- a/dp/wifi3.0/dp_rx_mon_feature.c
+++ b/dp/wifi3.0/dp_rx_mon_feature.c
@@ -684,9 +684,19 @@
 	return dp_mon_filter_update(pdev);
 }
 
-void
-dp_peer_set_rx_capture_enabled(struct dp_peer *peer, bool value)
+QDF_STATUS
+dp_peer_set_rx_capture_enabled(struct dp_pdev *pdev, struct dp_peer *peer,
+			       bool value, uint8_t *mac_addr)
 {
+	if (!peer) {
+		dp_err("Invalid Peer");
+		if (value)
+			return QDF_STATUS_E_FAILURE;
+		return QDF_STATUS_SUCCESS;
+	}
+
 	peer->rx_cap_enabled = value;
+
+	return QDF_STATUS_SUCCESS;
 }
 #endif /* WLAN_RX_PKT_CAPTURE_ENH */
diff --git a/dp/wifi3.0/dp_rx_mon_feature.h b/dp/wifi3.0/dp_rx_mon_feature.h
index f21135a..41b2296 100644
--- a/dp/wifi3.0/dp_rx_mon_feature.h
+++ b/dp/wifi3.0/dp_rx_mon_feature.h
@@ -76,12 +76,15 @@
 
 /**
  * dp_peer_set_rx_capture_enabled: Set rx_cap_enabled bit in peer
+ * @pdev: DP_PDEV handle
  * @peer_handle: Peer handle
  * @value: Enable/disable setting for rx_cap_enabled
+ * @mac_addr: peer mac address
  *
- * Return: None
+ * Return: status
  */
-void
-dp_peer_set_rx_capture_enabled(struct dp_peer *peer, bool value);
+QDF_STATUS dp_peer_set_rx_capture_enabled(struct dp_pdev *pdev,
+					  struct dp_peer *peer_handle,
+					  bool value, uint8_t *mac_addr);
 #endif /* WLAN_RX_PKT_CAPTURE_ENH */
 #endif /* _DP_RX_MON_FEATURE_H_ */
diff --git a/dp/wifi3.0/dp_rx_tag.c b/dp/wifi3.0/dp_rx_tag.c
index 0b3f600..9eb5e0a 100644
--- a/dp/wifi3.0/dp_rx_tag.c
+++ b/dp/wifi3.0/dp_rx_tag.c
@@ -284,7 +284,7 @@
 	if (qdf_likely(1 != dp_pdev->ppdu_info.rx_status.rxpcu_filter_pass))
 		return;
 
-	msdu_ppdu_id = hal_rx_hw_desc_get_ppduid_get(soc->hal_soc, rx_desc);
+	msdu_ppdu_id = hal_rx_get_ppdu_id(soc->hal_soc, rx_desc);
 
 	if (msdu_ppdu_id != dp_pdev->ppdu_info.com_info.ppdu_id) {
 		QDF_TRACE(QDF_MODULE_ID_DP,
diff --git a/dp/wifi3.0/dp_tx_capture.c b/dp/wifi3.0/dp_tx_capture.c
index 8d2ac96..e54de49 100644
--- a/dp/wifi3.0/dp_tx_capture.c
+++ b/dp/wifi3.0/dp_tx_capture.c
@@ -34,7 +34,8 @@
 #define MAX_MONITOR_HEADER (512)
 #define MAX_DUMMY_FRM_BODY (128)
 #define DP_BA_ACK_FRAME_SIZE (sizeof(struct ieee80211_ctlframe_addr2) + 36)
-#define DP_ACK_FRAME_SIZE (struct ieee80211_frame_min_one)
+#define DP_ACK_FRAME_SIZE (sizeof(struct ieee80211_frame_min_one))
+#define DP_CTS_FRAME_SIZE (sizeof(struct ieee80211_frame_min_one))
 #define DP_MAX_MPDU_64 64
 #define DP_NUM_WORDS_PER_PPDU_BITMAP_64 (DP_MAX_MPDU_64 >> 5)
 #define DP_NUM_BYTES_PER_PPDU_BITMAP_64 (DP_MAX_MPDU_64 >> 3)
@@ -154,20 +155,27 @@
  * based on global per-pdev setting or per-peer setting
  * @pdev: Datapath pdev handle
  * @peer: Datapath peer
+ * @mac_addr: peer mac address
  *
  * Return: true if feature is enabled on a per-pdev basis or if
  * enabled for the given peer when per-peer mode is set, false otherwise
  */
 inline bool
 dp_peer_or_pdev_tx_cap_enabled(struct dp_pdev *pdev,
-			       struct dp_peer *peer)
+			       struct dp_peer *peer, uint8_t *mac_addr)
 {
 	if ((pdev->tx_capture_enabled ==
 	     CDP_TX_ENH_CAPTURE_ENABLE_ALL_PEERS) ||
-	    ((pdev->tx_capture_enabled ==
-	      CDP_TX_ENH_CAPTURE_ENDIS_PER_PEER) &&
-	     peer->tx_cap_enabled))
-		return true;
+	    (pdev->tx_capture_enabled ==
+	      CDP_TX_ENH_CAPTURE_ENDIS_PER_PEER)) {
+		if (peer && peer->tx_cap_enabled)
+			return true;
+
+		/* do search based on mac address */
+		return is_dp_peer_mgmt_pkt_filter(pdev,
+						  HTT_INVALID_PEER,
+						  mac_addr);
+	}
 	return false;
 }
 
@@ -304,6 +312,11 @@
 			return;
 		}
 
+		if (!dp_peer_or_pdev_tx_cap_enabled(pdev, NULL, wh->i_addr1)) {
+			qdf_nbuf_free(nbuf);
+			return;
+		}
+
 		qdf_spin_lock_bh(
 			&pdev->tx_capture.ctl_mgmt_lock[type][subtype]);
 		qdf_nbuf_queue_add(&pdev->tx_capture.ctl_mgmt_q[type][subtype],
@@ -317,6 +330,208 @@
 	}
 }
 
+static inline int dp_peer_compare_mac_addr(void *addr1, void *addr2)
+{
+	union dp_align_mac_addr *mac_addr1 = (union dp_align_mac_addr *)addr1;
+	union dp_align_mac_addr *mac_addr2 = (union dp_align_mac_addr *)addr2;
+
+	return !((mac_addr1->align4.bytes_abcd == mac_addr2->align4.bytes_abcd)
+		 & (mac_addr1->align4.bytes_ef == mac_addr2->align4.bytes_ef));
+}
+
+/*
+ * dp_peer_tx_cap_search: filter mgmt pkt based on peer and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on matched and false on not found
+ */
+static
+bool dp_peer_tx_cap_search(struct dp_pdev *pdev,
+			   uint16_t peer_id, uint8_t *mac_addr)
+{
+	struct dp_pdev_tx_capture *tx_capture;
+	struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+	uint8_t i = 0;
+	bool found = false;
+
+	tx_capture = &pdev->tx_capture;
+
+	/* search based on mac address */
+	for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+		uint8_t *peer_mac_addr;
+
+		ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+		if (ptr_peer_mgmt_list->avail)
+			continue;
+		peer_mac_addr = ptr_peer_mgmt_list->mac_addr;
+		if (!dp_peer_compare_mac_addr(mac_addr,
+					      peer_mac_addr)) {
+			found = true;
+			break;
+		}
+	}
+	return found;
+}
+
+/*
+ * dp_peer_tx_cap_add_filter: add peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+bool dp_peer_tx_cap_add_filter(struct dp_pdev *pdev,
+			       uint16_t peer_id, uint8_t *mac_addr)
+{
+	struct dp_pdev_tx_capture *tx_capture;
+	struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+	uint8_t i = 0;
+	bool status = false;
+
+	tx_capture = &pdev->tx_capture;
+
+	if (dp_peer_tx_cap_search(pdev, peer_id, mac_addr)) {
+		/* mac address and peer_id already there */
+		QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+			  "%s: %d peer_id[%d] mac_addr[%pM] already there\n",
+			  __func__, __LINE__, peer_id, mac_addr);
+		return status;
+	}
+
+	for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+		ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+		if (!ptr_peer_mgmt_list->avail)
+			continue;
+		qdf_mem_copy(ptr_peer_mgmt_list->mac_addr,
+			     mac_addr, QDF_MAC_ADDR_SIZE);
+		ptr_peer_mgmt_list->avail = false;
+		ptr_peer_mgmt_list->peer_id = peer_id;
+		status = true;
+		break;
+	}
+
+	return status;
+}
+
+/*
+ * dp_peer_tx_cap_del_all_filter: delete all peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: void
+ */
+void dp_peer_tx_cap_del_all_filter(struct dp_pdev *pdev)
+{
+	struct dp_pdev_tx_capture *tx_capture;
+	struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+	uint8_t i = 0;
+
+	tx_capture = &pdev->tx_capture;
+
+	for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+		ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+		ptr_peer_mgmt_list->avail = true;
+		ptr_peer_mgmt_list->peer_id = HTT_INVALID_PEER;
+		qdf_mem_zero(ptr_peer_mgmt_list->mac_addr, QDF_MAC_ADDR_SIZE);
+	}
+}
+
+/*
+ * dp_peer_tx_cap_del_filter: delete peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+bool dp_peer_tx_cap_del_filter(struct dp_pdev *pdev,
+			       uint16_t peer_id, uint8_t *mac_addr)
+{
+	struct dp_pdev_tx_capture *tx_capture;
+	struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+	uint8_t i = 0;
+	bool status = false;
+
+	tx_capture = &pdev->tx_capture;
+
+	for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+		ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+		if (!dp_peer_compare_mac_addr(mac_addr,
+					      ptr_peer_mgmt_list->mac_addr) &&
+		    (!ptr_peer_mgmt_list->avail)) {
+			ptr_peer_mgmt_list->avail = true;
+			ptr_peer_mgmt_list->peer_id = HTT_INVALID_PEER;
+			qdf_mem_zero(ptr_peer_mgmt_list->mac_addr,
+				     QDF_MAC_ADDR_SIZE);
+			status = true;
+			break;
+		}
+	}
+
+	if (!status)
+		QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+			  "unable to delete peer[%d] mac[%pM] filter list",
+			  peer_id, mac_addr);
+	return status;
+}
+
+/*
+ * dp_peer_tx_cap_print_mgmt_filter: pradd peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+void dp_peer_tx_cap_print_mgmt_filter(struct dp_pdev *pdev,
+				      uint16_t peer_id, uint8_t *mac_addr)
+{
+	struct dp_pdev_tx_capture *tx_capture;
+	struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+	uint8_t i = 0;
+
+	tx_capture = &pdev->tx_capture;
+
+	QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+		  "peer filter list:");
+	for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+		ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+		QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+			  "peer_id[%d] mac_addr[%pM] avail[%d]",
+			  ptr_peer_mgmt_list->peer_id,
+			  ptr_peer_mgmt_list->mac_addr,
+			  ptr_peer_mgmt_list->avail);
+	}
+}
+
+/*
+ * dp_peer_mgmt_pkt_filter: filter mgmt pkt based on peer and mac address
+ * @pdev: DP PDEV handle
+ * @nbuf: buffer containing the ppdu_desc
+ *
+ * return: status
+ */
+bool is_dp_peer_mgmt_pkt_filter(struct dp_pdev *pdev,
+				uint32_t peer_id, uint8_t *mac_addr)
+{
+	bool found = false;
+
+	found = dp_peer_tx_cap_search(pdev, peer_id, mac_addr);
+	QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%s: %d peer_id[%d] mac_addr[%pM] found[%d]!",
+		  __func__, __LINE__, peer_id, mac_addr, found);
+
+	return found;
+}
+
 /**
  * dp_tx_ppdu_stats_attach - Initialize Tx PPDU stats and enhanced capture
  * @pdev: DP PDEV
@@ -325,7 +540,11 @@
  */
 void dp_tx_ppdu_stats_attach(struct dp_pdev *pdev)
 {
+	struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+	struct dp_pdev_tx_capture *tx_capture;
 	int i, j;
+
+	tx_capture = &pdev->tx_capture;
 	/* Work queue setup for HTT stats and tx capture handling */
 	qdf_create_work(0, &pdev->tx_capture.ppdu_stats_work,
 			dp_tx_ppdu_stats_process,
@@ -349,6 +568,14 @@
 	}
 	qdf_mem_zero(&pdev->tx_capture.dummy_ppdu_desc,
 		     sizeof(struct cdp_tx_completion_ppdu));
+
+	pdev->tx_capture.ptr_peer_mgmt_list = (struct dp_peer_mgmt_list *)
+			qdf_mem_malloc(sizeof(struct dp_peer_mgmt_list) *
+				       MAX_MGMT_PEER_FILTER);
+	for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+		ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+		ptr_peer_mgmt_list->avail = true;
+	}
 }
 
 /**
@@ -399,6 +626,8 @@
 				&pdev->tx_capture.ctl_mgmt_lock[i][j]);
 		}
 	}
+
+	qdf_mem_free(pdev->tx_capture.ptr_peer_mgmt_list);
 }
 
 /**
@@ -498,14 +727,15 @@
 				   struct dp_peer *peer)
 {
 	int ret = QDF_STATUS_E_FAILURE;
+	struct dp_pdev *pdev = desc->pdev;
 
-	if (peer && dp_peer_or_pdev_tx_cap_enabled(desc->pdev, peer) &&
+	if (peer &&
+	    dp_peer_or_pdev_tx_cap_enabled(pdev, peer, peer->mac_addr.raw) &&
 	    ((ts->status == HAL_TX_TQM_RR_FRAME_ACKED) ||
 	    (ts->status == HAL_TX_TQM_RR_REM_CMD_TX) ||
-	    ((ts->status == HAL_TX_TQM_RR_REM_CMD_AGED) && ts->transmit_cnt))) {
-		ret = dp_update_msdu_to_list(soc, desc->pdev,
-					     peer, ts, desc->nbuf);
-	}
+	    ((ts->status == HAL_TX_TQM_RR_REM_CMD_AGED) && ts->transmit_cnt)))
+		ret = dp_update_msdu_to_list(soc, pdev, peer, ts, desc->nbuf);
+
 	return ret;
 }
 
@@ -666,6 +896,8 @@
 			int tid;
 			struct dp_tx_tid *tx_tid;
 
+			/* set peer tx cap enabled to 0, when feature disable */
+			peer->tx_cap_enabled = 0;
 			for (tid = 0; tid < DP_MAX_TIDS; tid++) {
 				qdf_nbuf_t ppdu_nbuf = NULL;
 				struct cdp_tx_completion_ppdu *ppdu_desc =
@@ -742,6 +974,7 @@
 					&pdev->tx_capture.ctl_mgmt_lock[i][j]);
 			}
 		}
+		dp_peer_tx_cap_del_all_filter(pdev);
 	}
 
 	qdf_spin_unlock(&pdev->tx_capture.config_lock);
@@ -1411,6 +1644,7 @@
 					  void *desc)
 {
 	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[0];
 	struct ieee80211_ctlframe_addr2 *wh_min;
@@ -1497,15 +1731,17 @@
 	else {
 		peer = dp_peer_find_by_id(pdev->soc, user->peer_id);
 		if (peer) {
-			struct dp_vdev *vdev = NULL;
-
 			vdev = peer->vdev;
-			if (vdev)
-				qdf_mem_copy(wh_min->i_addr2,
-					     vdev->mac_addr.raw,
-					     QDF_MAC_ADDR_SIZE);
 			dp_peer_unref_del_find_by_id(peer);
+		} else {
+			vdev =
+			dp_get_vdev_from_soc_vdev_id_wifi3(pdev->soc,
+							   ppdu_desc->vdev_id);
 		}
+		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));
 	}
 
@@ -1544,6 +1780,7 @@
 	struct dp_pdev_tx_capture *ptr_tx_cap;
 	struct dp_peer *peer;
 	uint8_t rts_send;
+	struct dp_vdev *vdev = NULL;
 
 	rts_send = 0;
 	ptr_tx_cap = &pdev->tx_capture;
@@ -1595,16 +1832,20 @@
 		peer = dp_peer_find_by_id(pdev->soc,
 					  cur_ppdu_desc->user[0].peer_id);
 		if (peer) {
-			struct dp_vdev *vdev = NULL;
-
 			vdev = peer->vdev;
-			if (vdev)
-				qdf_mem_copy(&ppdu_desc->user[0].mac_addr,
-					     vdev->mac_addr.raw,
-					     QDF_MAC_ADDR_SIZE);
 			dp_peer_unref_del_find_by_id(peer);
+		} else {
+			uint8_t vdev_id;
+
+			vdev_id = ppdu_desc->vdev_id;
+			vdev = dp_get_vdev_from_soc_vdev_id_wifi3(pdev->soc,
+								  vdev_id);
 		}
 
+		if (vdev)
+			qdf_mem_copy(&ppdu_desc->user[0].mac_addr,
+				     vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE);
+
 		dp_send_dummy_mpdu_info_to_stack(pdev, ppdu_desc);
 	}
 }
@@ -1730,7 +1971,9 @@
 			qdf_nbuf_free(tx_capture_info.mpdu_nbuf);
 	}
 
-	if (ppdu_desc->resp_type == HTT_PPDU_STATS_ACK_EXPECTED_E)
+	if (ppdu_desc->resp_type == HTT_PPDU_STATS_ACK_EXPECTED_E &&
+	    ppdu_desc->user[0].completion_status ==
+	    HTT_PPDU_STATS_USER_STATUS_OK)
 		dp_gen_ack_rx_frame(pdev, &tx_capture_info);
 }
 
@@ -2198,6 +2441,12 @@
 		subtype = 0;
 	}
 
+	if (!dp_peer_or_pdev_tx_cap_enabled(pdev, NULL,
+					    ppdu_desc->user[0].mac_addr)) {
+		qdf_nbuf_free(nbuf_ppdu_desc);
+		status = 0;
+		goto free_ppdu_desc;
+	}
 	switch (ppdu_desc->htt_frame_type) {
 	case HTT_STATS_FTYPE_TIDQ_DATA_SU:
 	case HTT_STATS_FTYPE_TIDQ_DATA_MU:
@@ -2275,7 +2524,7 @@
 			    HTT_PPDU_STATS_USER_STATUS_FILTERED) {
 				qdf_nbuf_free(nbuf_ppdu_desc);
 				status = 0;
-				goto free_ppdu_desc;
+				goto insert_mgmt_buf_to_queue;
 			}
 
 			/*
@@ -2284,6 +2533,7 @@
 			qdf_nbuf_queue_add(retries_q, nbuf_ppdu_desc);
 			status = 0;
 
+insert_mgmt_buf_to_queue:
 			/*
 			 * insert the mgmt_ctl buffer back to
 			 * the queue
@@ -2874,6 +3124,7 @@
 			uint16_t tid = 0;
 			uint32_t num_msdu = 0;
 			uint32_t qlen = 0;
+			uint16_t peer_id;
 
 			qdf_nbuf_queue_init(&head_msdu);
 			qdf_nbuf_queue_init(&head_xretries);
@@ -2937,19 +3188,19 @@
 				continue;
 			}
 
-			peer = dp_peer_find_by_id(pdev->soc,
-						  ppdu_desc->user[0].peer_id);
-			/**
-			 * peer can be NULL
-			 */
-			if (!peer) {
-				qdf_nbuf_free(nbuf);
-				continue;
-			}
-
 			if ((ppdu_desc->frame_type == CDP_PPDU_FTYPE_DATA) ||
 			    (ppdu_desc->num_mpdu &&
 			     ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR)) {
+				peer_id = ppdu_desc->user[0].peer_id;
+				peer = dp_peer_find_by_id(pdev->soc, peer_id);
+				/**
+				 * peer can be NULL
+				 */
+				if (!peer) {
+					qdf_nbuf_free(nbuf);
+					continue;
+				}
+
 				/**
 				 * check whether it is bss peer,
 				 * if bss_peer no need to process further
@@ -2958,7 +3209,7 @@
 				 */
 				if (peer->bss_peer ||
 				    !dp_peer_or_pdev_tx_cap_enabled(pdev,
-				    peer)) {
+				    peer, peer->mac_addr.raw)) {
 					dp_peer_unref_del_find_by_id(peer);
 					qdf_nbuf_free(nbuf);
 					continue;
@@ -3065,6 +3316,8 @@
 					  ppdu_desc->user[0].start_seq,
 					  ppdu_cnt,
 					  ppdu_desc_cnt);
+
+				dp_peer_unref_del_find_by_id(peer);
 			} else {
 				/*
 				 * other packet frame also added to
@@ -3073,7 +3326,6 @@
 				nbuf_ppdu_desc_list[ppdu_desc_cnt++] = nbuf;
 			}
 
-			dp_peer_unref_del_find_by_id(peer);
 		}
 
 		/*
@@ -3263,6 +3515,107 @@
 			    (frm - (uint8_t *)qdf_nbuf_data(mpdu_nbuf)));
 }
 
+static void dp_gen_cts_frame(struct hal_rx_ppdu_info *ppdu_info,
+			     struct dp_peer *peer,
+			     qdf_nbuf_t mpdu_nbuf)
+{
+	struct ieee80211_frame_min_one *wh_addr1;
+	uint16_t duration;
+
+	wh_addr1 = (struct ieee80211_frame_min_one *)
+		qdf_nbuf_data(mpdu_nbuf);
+
+	wh_addr1->i_fc[0] = 0;
+	wh_addr1->i_fc[1] = 0;
+	wh_addr1->i_fc[0] =  IEEE80211_FC0_VERSION_0 |
+		IEEE80211_FC0_TYPE_CTL |
+		IEEE80211_FC0_SUBTYPE_CTS;
+	qdf_mem_copy(wh_addr1->i_addr1, &peer->mac_addr.raw[0],
+		     QDF_MAC_ADDR_SIZE);
+	duration = (ppdu_info->rx_status.duration > SIFS_INTERVAL) ?
+		ppdu_info->rx_status.duration - SIFS_INTERVAL : 0;
+	wh_addr1->i_dur[0] = duration & 0xff;
+	wh_addr1->i_dur[1] = (duration >> 8) & 0xff;
+	qdf_nbuf_set_pktlen(mpdu_nbuf, sizeof(*wh_addr1));
+}
+
+/**
+ * dp_send_cts_frame_to_stack(): Function to deliver HW generated CTS frame
+ *	in reponse to RTS
+ * @soc: core txrx main context
+ * @pdev: DP pdev object
+ * @ppdu_info: HAL RX PPDU info retrieved from status ring TLV
+ *
+ * return: status
+ */
+QDF_STATUS dp_send_cts_frame_to_stack(struct dp_soc *soc,
+				      struct dp_pdev *pdev,
+				      struct hal_rx_ppdu_info *ppdu_info)
+{
+	struct cdp_tx_indication_info tx_capture_info;
+	struct mon_rx_user_status *rx_user_status =
+		&ppdu_info->rx_user_status[0];
+	struct dp_ast_entry *ast_entry;
+	uint32_t peer_id;
+	struct dp_peer *peer;
+
+	if (rx_user_status->ast_index >=
+	    wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&soc->ast_lock);
+	ast_entry = soc->ast_table[rx_user_status->ast_index];
+	if (!ast_entry) {
+		qdf_spin_unlock_bh(&soc->ast_lock);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	peer = ast_entry->peer;
+	if (!peer || peer->peer_ids[0] == HTT_INVALID_PEER) {
+		qdf_spin_unlock_bh(&soc->ast_lock);
+		return QDF_STATUS_E_FAILURE;
+	}
+	peer_id = peer->peer_ids[0];
+	qdf_spin_unlock_bh(&soc->ast_lock);
+
+	peer = dp_peer_find_by_id(soc, peer_id);
+	if (!peer)
+		return QDF_STATUS_E_FAILURE;
+
+	if (!dp_peer_or_pdev_tx_cap_enabled(pdev, NULL, peer->mac_addr.raw)) {
+		dp_peer_unref_del_find_by_id(peer);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	set_mpdu_info(&tx_capture_info,
+		      &ppdu_info->rx_status, rx_user_status);
+	tx_capture_info.mpdu_info.mcs = rx_user_status->mcs;
+	/* ppdu_desc is not required for legacy frames */
+	tx_capture_info.ppdu_desc = NULL;
+
+	tx_capture_info.mpdu_nbuf =
+		qdf_nbuf_alloc(pdev->soc->osdev,
+			       MAX_MONITOR_HEADER +
+			       DP_CTS_FRAME_SIZE,
+			       MAX_MONITOR_HEADER,
+			       4, FALSE);
+
+	if (!tx_capture_info.mpdu_nbuf) {
+		dp_peer_unref_del_find_by_id(peer);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	dp_gen_cts_frame(ppdu_info, peer,
+				 tx_capture_info.mpdu_nbuf);
+	dp_peer_unref_del_find_by_id(peer);
+	dp_wdi_event_handler(WDI_EVENT_TX_DATA, pdev->soc,
+			     &tx_capture_info, HTT_INVALID_PEER,
+			     WDI_NO_VAL, pdev->pdev_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * dp_send_ack_frame_to_stack(): Function to generate BA or ACK frame and
  * send to upper layer on received unicast frame
@@ -3286,6 +3639,7 @@
 	uint32_t ast_index;
 	uint32_t i;
 	bool bar_frame;
+	uint8_t *ptr_mac_addr;
 
 	rx_status = &ppdu_info->rx_status;
 
@@ -3301,6 +3655,10 @@
 		return QDF_STATUS_SUCCESS;
 	}
 
+	if (ppdu_info->sw_frame_group_id ==
+	    HAL_MPDU_SW_FRAME_GROUP_CTRL_RTS)
+		return dp_send_cts_frame_to_stack(soc, pdev, ppdu_info);
+
 	if (ppdu_info->sw_frame_group_id == HAL_MPDU_SW_FRAME_GROUP_CTRL_BAR)
 		bar_frame = true;
 	else
@@ -3324,6 +3682,10 @@
 		ast_index = rx_user_status->ast_index;
 		if (ast_index >=
 		    wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) {
+			ptr_mac_addr = &ppdu_info->nac_info.mac_addr2[0];
+			if (!dp_peer_or_pdev_tx_cap_enabled(pdev,
+							    NULL, ptr_mac_addr))
+				continue;
 			set_mpdu_info(&tx_capture_info,
 				      rx_status, rx_user_status);
 			tx_capture_info.mpdu_nbuf =
@@ -3362,7 +3724,8 @@
 			continue;
 
 		if (!dp_peer_or_pdev_tx_cap_enabled(pdev,
-						    peer)) {
+						    NULL,
+						    peer->mac_addr.raw)) {
 			dp_peer_unref_del_find_by_id(peer);
 			continue;
 		}
@@ -3406,16 +3769,56 @@
 
 /**
  * dp_peer_set_tx_capture_enabled: Set tx_cap_enabled bit in peer
+ * @pdev: DP PDEV handle
  * @peer: Peer handle
  * @value: Enable/disable setting for tx_cap_enabled
+ * @peer_mac: peer mac address
  *
- * Return: None
+ * Return: QDF_STATUS
  */
-void
-dp_peer_set_tx_capture_enabled(struct dp_peer *peer, bool value)
+QDF_STATUS
+dp_peer_set_tx_capture_enabled(struct dp_pdev *pdev,
+			       struct dp_peer *peer, uint8_t value,
+			       uint8_t *peer_mac)
 {
-	peer->tx_cap_enabled = value;
-	if (!value)
-		dp_peer_tx_cap_tid_queue_flush(peer);
+	uint32_t peer_id = HTT_INVALID_PEER;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (value) {
+		if (dp_peer_tx_cap_add_filter(pdev, peer_id, peer_mac)) {
+			if (peer)
+				peer->tx_cap_enabled = value;
+			status = QDF_STATUS_SUCCESS;
+		}
+	} else {
+		if (dp_peer_tx_cap_del_filter(pdev, peer_id, peer_mac)) {
+			if (peer)
+				peer->tx_cap_enabled = value;
+			status = QDF_STATUS_SUCCESS;
+		}
+	}
+
+	return status;
+}
+
+/*
+ * dp_peer_tx_capture_filter_check: check filter is enable for the filter
+ * and update tx_cap_enabled flag
+ * @pdev: DP PDEV handle
+ * @peer: DP PEER handle
+ *
+ * return: void
+ */
+void dp_peer_tx_capture_filter_check(struct dp_pdev *pdev,
+				     struct dp_peer *peer)
+{
+	if (!peer)
+		return;
+
+	if (dp_peer_tx_cap_search(pdev, peer->peer_ids[0],
+				  peer->mac_addr.raw)) {
+		peer->tx_cap_enabled = 1;
+	}
+	return;
 }
 #endif
diff --git a/dp/wifi3.0/dp_tx_capture.h b/dp/wifi3.0/dp_tx_capture.h
index 6f85eaf..016675c 100644
--- a/dp/wifi3.0/dp_tx_capture.h
+++ b/dp/wifi3.0/dp_tx_capture.h
@@ -35,6 +35,16 @@
 #define TXCAP_MAX_SUBTYPE \
 	((IEEE80211_FC0_SUBTYPE_MASK >> IEEE80211_FC0_SUBTYPE_SHIFT) + 1)
 
+#define SIFS_INTERVAL 16
+
+#define MAX_MGMT_PEER_FILTER 16
+struct dp_peer_mgmt_list {
+	uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
+	uint32_t mgmt_pkt_counter;
+	uint16_t peer_id;
+	bool avail;
+};
+
 struct dp_pdev_tx_capture {
 	/* For deferred PPDU status processing */
 	qdf_spinlock_t ppdu_stats_lock;
@@ -60,6 +70,7 @@
 	qdf_spinlock_t config_lock;
 	uint32_t htt_frame_type[TX_CAP_HTT_MAX_FTYPE];
 	struct cdp_tx_completion_ppdu dummy_ppdu_desc;
+	struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
 };
 
 /* Tx TID */
@@ -261,12 +272,73 @@
 
 /**
  * dp_peer_set_tx_capture_enabled: Set tx_cap_enabled bit in peer
+ * @pdev: DP PDEV handle
  * @peer: Peer handle
  * @value: Enable/disable setting for tx_cap_enabled
+ * @peer_mac: peer_mac Enable/disable setting for tx_cap_enabled
  *
- * Return: None
+ * Return: QDF_STATUS
  */
-void
-dp_peer_set_tx_capture_enabled(struct dp_peer *peer, bool value);
+QDF_STATUS
+dp_peer_set_tx_capture_enabled(struct dp_pdev *pdev,
+			       struct dp_peer *peer, uint8_t value,
+			       uint8_t *peer_mac);
+
+/*
+ * dp_peer_tx_cap_add_filter: add peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+bool dp_pdev_tx_cap_add_filter(struct dp_pdev *pdev,
+			       uint16_t peer_id, uint8_t *mac_addr);
+
+/*
+ * dp_peer_tx_cap_del_filter: delete peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+bool dp_peer_tx_cap_del_filter(struct dp_pdev *pdev,
+			       uint16_t peer_id, uint8_t *mac_addr);
+
+/*
+ * dp_peer_tx_cap_print_mgmt_filter: pradd peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+void dp_peer_tx_cap_print_mgmt_filter(struct dp_pdev *pdev,
+				      uint16_t peer_id, uint8_t *mac_addr);
+
+/*
+ * dp_peer_mgmt_pkt_filter: filter mgmt pkt based on peer and mac address
+ * @pdev: DP PDEV handle
+ * @nbuf: buffer containing the ppdu_desc
+ *
+ * return: status
+ */
+bool is_dp_peer_mgmt_pkt_filter(struct dp_pdev *pdev,
+				uint32_t peer_id, uint8_t *mac_addr);
+
+/*
+ * dp_peer_tx_capture_filter_check: check filter is enable for the filter
+ * and update tx_cap_enabled flag
+ * @pdev: DP PDEV handle
+ * @peer: DP PEER handle
+ *
+ * return: void
+ */
+void dp_peer_tx_capture_filter_check(struct dp_pdev *pdev,
+				     struct dp_peer *peer);
 #endif
 #endif
diff --git a/target_if/cfr/src/target_if_cfr_6018.c b/target_if/cfr/src/target_if_cfr_6018.c
index 06933c9..afea3aa 100644
--- a/target_if/cfr/src/target_if_cfr_6018.c
+++ b/target_if/cfr/src/target_if_cfr_6018.c
@@ -262,8 +262,8 @@
 	uint8_t *usermac = NULL;
 
 	cfr_debug("<METADATA><%u>\n"
-		  "start_magic_num = %d\n"
-		  "vendorid = %d\n"
+		  "start_magic_num = 0x%x\n"
+		  "vendorid = 0x%x\n"
 		  "cfr_metadata_version = %d\n"
 		  "cfr_data_version = %d\n"
 		  "chip_type = %d\n"
@@ -279,7 +279,7 @@
 		  "cfr_capture_type = %d\n"
 		  "sts_count = %d\n"
 		  "num_rx_chain = %d\n"
-		  "timestamp = %d\n"
+		  "timestamp = 0x%x\n"
 		  "length = %d\n"
 		  "is_mu_ppdu = %d\n"
 		  "num_users = %d\n",
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 2831f2a..bfea671 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018, 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
@@ -398,6 +398,10 @@
 UCFG_VDEV_CP_STATS_GET_FUNCS(rx_wrongbss);
 UCFG_VDEV_CP_STATS_GET_FUNCS(rx_wrongdir);
 UCFG_VDEV_CP_STATS_GET_FUNCS(rx_ssid_mismatch);
+UCFG_VDEV_CP_STATS_GET_FUNCS(peer_delete_req);
+UCFG_VDEV_CP_STATS_GET_FUNCS(peer_delete_resp);
+UCFG_VDEV_CP_STATS_GET_FUNCS(peer_delete_all_req);
+UCFG_VDEV_CP_STATS_GET_FUNCS(peer_delete_all_resp);
 
 #define UCFG_VDEV_UCAST_CP_STATS_SET_FUNCS(field) \
 	static inline void \
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 0722380..002c0b7 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018, 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
@@ -276,6 +276,10 @@
 VDEV_CP_STATS_GET_FUNCS(rx_wrongbss);
 VDEV_CP_STATS_GET_FUNCS(rx_wrongdir);
 VDEV_CP_STATS_GET_FUNCS(rx_ssid_mismatch);
+VDEV_CP_STATS_GET_FUNCS(peer_delete_req);
+VDEV_CP_STATS_GET_FUNCS(peer_delete_resp);
+VDEV_CP_STATS_GET_FUNCS(peer_delete_all_req);
+VDEV_CP_STATS_GET_FUNCS(peer_delete_all_resp);
 
 static inline void vdev_cp_stats_reset(struct wlan_objmgr_vdev *vdev)
 {
diff --git a/wmi/src/wmi_unified_ap_tlv.c b/wmi/src/wmi_unified_ap_tlv.c
index 9a1397e..cd60c68 100644
--- a/wmi/src/wmi_unified_ap_tlv.c
+++ b/wmi/src/wmi_unified_ap_tlv.c
@@ -2540,14 +2540,15 @@
 	if (!param_buf->num_vdev_ids_bitmap)
 		return QDF_STATUS_E_FAILURE;
 
-	if (param_buf->num_vdev_ids_bitmap > sizeof(param->vdev_id_bmap)) {
+	if ((param_buf->num_vdev_ids_bitmap * sizeof(uint32_t)) >
+			sizeof(param->vdev_id_bmap)) {
 		WMI_LOGE("vdevId bitmap overflow size:%d",
 			 param_buf->num_vdev_ids_bitmap);
 		return QDF_STATUS_E_FAILURE;
 	}
 
 	qdf_mem_copy(param->vdev_id_bmap, param_buf->vdev_ids_bitmap,
-		     param_buf->num_vdev_ids_bitmap);
+		     param_buf->num_vdev_ids_bitmap * sizeof(uint32_t));
 
 	WMI_LOGD("vdev_id_bmap :0x%x%x", param->vdev_id_bmap[1],
 		 param->vdev_id_bmap[0]);
diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c
index 6a1c80d..2bfcbd3 100644
--- a/wmi/src/wmi_unified_non_tlv.c
+++ b/wmi/src/wmi_unified_non_tlv.c
@@ -10690,7 +10690,9 @@
 	wmi_service[wmi_service_cfr_capture_support] =
 		WMI_SERVICE_CFR_CAPTURE_SUPPORT;
 	wmi_service[wmi_service_rx_fse_support] = WMI_SERVICE_UNAVAILABLE;
-	wmi_service[wmi_service_bw_165mhz_support] =
+	wmi_service[wmi_service_bw_restricted_80p80_support] =
+		WMI_SERVICE_UNAVAILABLE;
+	wmi_service[wmi_service_nss_ratio_to_host_support] =
 		WMI_SERVICE_UNAVAILABLE;
 }