Merge "qca-wifi: Assign proper precac_index for legacy preCAC"
diff --git a/dp/wifi3.0/dp_full_mon.c b/dp/wifi3.0/dp_full_mon.c
index c77751b..c29b39f 100644
--- a/dp/wifi3.0/dp_full_mon.c
+++ b/dp/wifi3.0/dp_full_mon.c
@@ -43,7 +43,7 @@
  *
  * Return: QDF_STATUS
  */
-static inline QDF_STATUS
+static inline enum dp_mon_reap_status
 dp_rx_mon_status_buf_validate(struct dp_pdev *pdev, uint32_t mac_id)
 {
 	struct dp_soc *soc = pdev->soc;
@@ -58,8 +58,9 @@
 	uint32_t tlv_tag;
 	void *rx_tlv;
 	struct hal_rx_ppdu_info *ppdu_info;
-	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	enum dp_mon_reap_status status = dp_mon_status_match;
 	QDF_STATUS buf_status;
+	uint32_t ppdu_id_diff;
 
 	mon_status_srng = soc->rxdma_mon_status_ring[mac_id].hal_srng;
 
@@ -85,8 +86,9 @@
 	ring_entry = hal_srng_src_peek_n_get_next(hal_soc, mon_status_srng);
 	if (!ring_entry) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
-			"%s %d : HAL SRNG entry is NULL srng:-- %pK",
-			__func__, __LINE__, mon_status_srng);
+			  "%s %d : HAL SRNG entry is NULL srng:-- %pK",
+			  __func__, __LINE__, mon_status_srng);
+		status = dp_mon_status_replenish;
 		goto done;
 	}
 
@@ -101,6 +103,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;
 		goto done;
 	}
 
@@ -127,7 +130,7 @@
 			     "for nbuf: %pK buf_addr: %llx"),
 			     status_nbuf, buf_paddr);
 		pdev->rx_mon_stats.tlv_tag_status_err++;
-		pdev->hold_mon_dest_ring = true;
+		status = dp_mon_status_no_dma;
 		goto done;
 	}
 
@@ -147,17 +150,23 @@
 		pdev->status_buf_addr = buf_paddr;
 	}
 
-	/* If Monitor destination ring is on hold and ppdu id matches,
-	 * deliver PPDU data which was on hold.
-	 */
-	if (pdev->hold_mon_dest_ring &&
-	    (pdev->mon_desc->ppdu_id == pdev->ppdu_info.com_info.ppdu_id)) {
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
-			  FL("Monitor destination was on Hold "
-			     "PPDU id matched"));
+	if (pdev->mon_desc->ppdu_id < pdev->ppdu_info.com_info.ppdu_id) {
+		status = dp_mon_status_lead;
 
-		pdev->hold_mon_dest_ring = false;
-		goto done;
+		/* For wrap around case */
+		ppdu_id_diff = pdev->ppdu_info.com_info.ppdu_id -
+			       pdev->mon_desc->ppdu_id;
+
+		if (ppdu_id_diff > DP_RX_MON_PPDU_ID_WRAP)
+			status = dp_mon_status_lag;
+
+	} else if (pdev->mon_desc->ppdu_id > pdev->ppdu_info.com_info.ppdu_id) {
+		status = dp_mon_status_lag;
+		/* For wrap around case */
+		ppdu_id_diff = pdev->mon_desc->ppdu_id -
+			       pdev->ppdu_info.com_info.ppdu_id;
+		if (ppdu_id_diff > DP_RX_MON_PPDU_ID_WRAP)
+			status = dp_mon_status_lead;
 	}
 
 	if ((pdev->mon_desc->status_buf.paddr != buf_paddr) ||
@@ -167,45 +176,12 @@
 			     "status_ppdu_id: %d dest_ppdu_id: %d "
 			     "status_addr: %llx status_buf_cookie: %d "
 			     "dest_addr: %llx tlv_tag: %d"
-			     " status_nbuf: %pK"),
+			     " status_nbuf: %pK pdev->hold_mon_dest: %d"),
 			      pdev->ppdu_info.com_info.ppdu_id,
 			      pdev->mon_desc->ppdu_id, pdev->status_buf_addr,
 			      rx_buf_cookie,
 			      pdev->mon_desc->status_buf.paddr, tlv_tag,
-			      status_nbuf);
-	}
-
-	/* Monitor Status ring is reaped in two cases:
-	 * a. If first status buffer's buf_addr_info matches
-	 * with latched status buffer addr info in monitor
-	 * destination ring.
-	 * b. If monitor status ring is lagging behind
-	 * monitor destination ring. Hold on to monitor
-	 * destination ring in this case until status ring
-	 * and destination ring ppdu id matches.
-	 */
-	if ((pdev->mon_desc->status_buf.paddr == buf_paddr) ||
-	    (pdev->mon_desc->ppdu_id > pdev->ppdu_info.com_info.ppdu_id)) {
-		if (pdev->mon_desc->ppdu_id >
-		    pdev->ppdu_info.com_info.ppdu_id) {
-
-			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
-				  FL("Monitor status ring is lagging behind "
-				     "monitor destination ring "
-				     "status_ppdu_id: %d dest_ppdu_id: %d "
-				     "status_nbuf: %pK tlv_tag: %d "
-				     "status_addr: %llx dest_addr: %llx "),
-				     ppdu_info->com_info.ppdu_id,
-				     pdev->mon_desc->ppdu_id,
-				     status_nbuf, tlv_tag,
-				     pdev->status_buf_addr,
-				     pdev->mon_desc->status_buf.paddr);
-
-			pdev->rx_mon_stats.ppdu_id_mismatch++;
-			pdev->rx_mon_stats.status_ppdu_drop++;
-			pdev->hold_mon_dest_ring = true;
-		}
-		status = QDF_STATUS_SUCCESS;
+			      status_nbuf, pdev->hold_mon_dest_ring);
 	}
 done:
 	hal_srng_access_end(hal_soc, mon_status_srng);
@@ -279,6 +255,7 @@
 			qdf_mem_free(mpdu);
 		}
 	}
+	pdev->mon_desc->drop_ppdu = 0;
 }
 
 /*
@@ -338,41 +315,69 @@
 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
 	uint8_t status_buf_count;
 	uint32_t work_done = 0;
+	enum dp_mon_reap_status status;
 
 	status_buf_count = desc_info->status_buf_count;
 	desc_info->drop_ppdu = false;
 
-	if (dp_rx_mon_status_buf_validate(pdev, mac_id) == QDF_STATUS_SUCCESS)
+	status = dp_rx_mon_status_buf_validate(pdev, mac_id);
+	switch (status) {
+		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:
+			/* If status_ppdu_id is lagging behind destination,
+			 * a. Hold on to destination ring
+			 * b. Drop status ppdus until ppdu id matches
+			 * c. Increment stats for ppdu_id mismatch and
+			 *    status ppdu drop
+			 */
+			pdev->hold_mon_dest_ring = true;
+			pdev->rx_mon_stats.ppdu_id_mismatch++;
+			pdev->rx_mon_stats.status_ppdu_drop++;
+			break;
+		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
+			 *    can be dropped.
+			 * c. Increment stats for ppdu_id mismatch and
+			 *    destination ppdu drop
+			 */
+			desc_info->drop_ppdu = true;
+			pdev->hold_mon_dest_ring = false;
+			pdev->rx_mon_stats.ppdu_id_mismatch++;
+			pdev->rx_mon_stats.dest_ppdu_drop++;
+			break;
+		case dp_mon_status_replenish:
+			/* If status ring hp entry is NULL, replenish it */
+			work_done = dp_rx_mon_status_process(soc, mac_id, 1);
+			break;
+		case dp_mon_status_match:
+			/* If status ppdu id matches with destnation,
+			 * unhold monitor destination ring and deliver ppdu
+			 */
+			pdev->hold_mon_dest_ring = false;
+			break;
+		default:
+			dp_err("mon reap status is not supported");
+	}
+
+	/* If status ring is lagging behind detination ring,
+	 * reap only one status buffer
+	 */
+	if (status == dp_mon_status_lag)
+		status_buf_count = 1;
+
+	if (status == dp_mon_status_lag ||
+	    status == dp_mon_status_match) {
 		work_done = dp_rx_mon_status_process(soc,
 						     mac_id,
 						     status_buf_count);
-
-	if (desc_info->ppdu_id != pdev->ppdu_info.com_info.ppdu_id) {
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
-			  FL("Monitor: PPDU id mismatch "
-			     "status_ppdu_id: %d dest_ppdu_id: %d "
-			     "status_addr: %llx dest_addr: %llx "
-			     "count: %d quota: %d work_done: %d "),
-			      pdev->ppdu_info.com_info.ppdu_id,
-			      pdev->mon_desc->ppdu_id, pdev->status_buf_addr,
-			      pdev->mon_desc->status_buf.paddr,
-			       status_buf_count, quota, work_done);
-	}
-
-	if (desc_info->ppdu_id < pdev->ppdu_info.com_info.ppdu_id) {
-		pdev->rx_mon_stats.ppdu_id_mismatch++;
-		desc_info->drop_ppdu = true;
-		pdev->rx_mon_stats.dest_ppdu_drop++;
-
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
-			  FL("Monitor destination ring is lagging behind "
-			     "monitor status ring "
-			     "status_ppdu_id: %d dest_ppdu_id: %d "
-			     "status_addr: %llx dest_addr: %llx "),
-			     pdev->ppdu_info.com_info.ppdu_id,
-			     pdev->mon_desc->ppdu_id,
-			     pdev->status_buf_addr,
-			     pdev->mon_desc->status_buf.paddr);
 	}
 
 	return work_done;
@@ -594,44 +599,92 @@
 
 	struct dp_soc *soc = pdev->soc;
 	struct hal_rx_mon_desc_info *desc_info = pdev->mon_desc;
-	uint32_t work_done = 0;
-	bool hold_mon_dest_ring = false;
+	uint32_t work_done = 0, work = 0;
+	bool deliver_ppdu = false;
+	enum dp_mon_reap_status status;
 
 	while (pdev->hold_mon_dest_ring) {
-		if (dp_rx_mon_status_buf_validate(pdev, mac_id) == QDF_STATUS_SUCCESS) {
-			work_done = dp_rx_mon_status_process(soc, mac_id, 1);
-		}
-		quota -= work_done;
+		status = dp_rx_mon_status_buf_validate(pdev, mac_id);
 
-		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
-			  FL("Hold on Monitor destination ring "
-			      "work_done: %d quota: %d status_ppdu_id: %d "
-			      "dest_ppdu_id: %d s_addr: %llx d_addr: %llx "),
-			      work_done, quota,
-			      pdev->ppdu_info.com_info.ppdu_id,
-			      desc_info->ppdu_id, pdev->status_buf_addr,
-			      desc_info->status_buf.paddr);
-
-		hold_mon_dest_ring = true;
-
-		if (!quota)
-			return quota;
-	}
-	if (hold_mon_dest_ring) {
-		if (quota >= desc_info->status_buf_count) {
-			qdf_err("DEBUG:");
-			work_done = dp_rx_mon_status_process(soc, mac_id,
-							     desc_info->status_buf_count);
-			dp_rx_monitor_deliver_ppdu(soc, mac_id);
-			hold_mon_dest_ring = false;
-		} else {
+		switch (status) {
+			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;
-			return quota;
+			break;
+			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
+			 * c. Increment stats for ppdu_id mismatch and
+			 *    status ppdu drop
+			 */
+			pdev->hold_mon_dest_ring = true;
+			pdev->rx_mon_stats.ppdu_id_mismatch++;
+			pdev->rx_mon_stats.status_ppdu_drop++;
+			break;
+			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
+			 *    can be dropped.
+			 * c. Increment stats for ppdu_id mismatch and
+			 *    destination ppdu drop
+			 */
+			desc_info->drop_ppdu = true;
+			pdev->hold_mon_dest_ring = false;
+			pdev->rx_mon_stats.ppdu_id_mismatch++;
+			pdev->rx_mon_stats.dest_ppdu_drop++;
+			break;
+			case dp_mon_status_replenish:
+			/* If status ring hp entry is NULL, replenish it */
+			work = dp_rx_mon_status_process(soc, mac_id, 1);
+			break;
+			case dp_mon_status_match:
+			/* If status ppdu id matches with destnation,
+			 * unhold monitor destination ring and deliver ppdu
+			 */
+			pdev->hold_mon_dest_ring = false;
+			break;
+			default:
+				dp_err("mon reap status is not supported");
 		}
-		quota -= work_done;
+
+		/* When status ring entry's DMA is not done or
+		 * status ring entry is replenished, ppdu status is not
+		 * 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)) {
+			return work_done;
+		}
+
+		if (status == dp_mon_status_lag) {
+			work = dp_rx_mon_status_process(soc, mac_id, 1);
+
+			if (!work)
+				return 0;
+
+			work_done += work;
+		}
+		deliver_ppdu = true;
 	}
 
-	return quota;
+	if (deliver_ppdu) {
+		if (pdev->mon_desc->drop_ppdu) {
+			dp_rx_mon_drop_ppdu(pdev, mac_id);
+			return work_done;
+		}
+
+		work_done += dp_rx_mon_status_process(soc, mac_id,
+				desc_info->status_buf_count);
+		dp_rx_monitor_deliver_ppdu(soc, mac_id);
+	}
+
+	return work_done;
 }
 
 /**
@@ -653,7 +706,7 @@
 	union dp_rx_desc_list_elem_t *tail_desc = NULL;
 	uint32_t rx_bufs_reaped = 0;
 	struct dp_mon_mpdu *mon_mpdu;
-	struct cdp_pdev_mon_stats *rx_mon_stats = &pdev->rx_mon_stats;
+	struct cdp_pdev_mon_stats *rx_mon_stats;
 	hal_rxdma_desc_t ring_desc;
 	hal_soc_handle_t hal_soc;
 	hal_ring_handle_t mon_dest_srng;
@@ -664,28 +717,36 @@
 	QDF_STATUS status;
 	uint32_t work_done = 0;
 
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
+			  "pdev is null for mac_id = %d", mac_id);
+		return work_done;
+	}
+
 	qdf_spin_lock_bh(&pdev->mon_lock);
 	if (qdf_unlikely(!dp_soc_is_full_mon_enable(pdev))) {
-		quota -= dp_rx_mon_status_process(soc, mac_id, quota);
+		work_done += dp_rx_mon_status_process(soc, mac_id, quota);
 		qdf_spin_unlock_bh(&pdev->mon_lock);
-		return quota;
+		return work_done;
 	}
 
 	desc_info = pdev->mon_desc;
 
-	quota = dp_rx_mon_deliver_prev_ppdu(pdev, mac_id, quota);
+	rx_mon_stats = &pdev->rx_mon_stats;
 
-	/* Do not proceed if quota expires */
-	if (!quota || pdev->hold_mon_dest_ring) {
+	work_done = dp_rx_mon_deliver_prev_ppdu(pdev, mac_id, quota);
+
+	/* Do not proceed if work_done zero */
+	if (!work_done && pdev->hold_mon_dest_ring) {
 		qdf_spin_unlock_bh(&pdev->mon_lock);
-		return quota;
+		return work_done;
 	}
 
 	mon_dest_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_for_pdev);
 
 	if (qdf_unlikely(!mon_dest_srng ||
 			 !hal_srng_initialized(mon_dest_srng))) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  FL("HAL Monitor Destination Ring Init Failed -- %pK"),
 			  mon_dest_srng);
 		goto done1;
@@ -791,6 +852,23 @@
 			continue;
 		}
 
+		/* It is observed sometimes that, ppdu_id, status_buf_addr
+		 * and link desc addr is NULL, this WAR is to handle same
+		 */
+
+		if (!desc_info->ppdu_id && !desc_info->status_buf.paddr) {
+			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
+				  FL("ppdu_id: %d ring_entry: %pK"
+				     "status_buf_count: %d rxdma_push: %d"
+				     "rxdma_err: %d link_desc: %pK "),
+				  desc_info->ppdu_id, ring_desc,
+				  desc_info->status_buf_count,
+				  desc_info->rxdma_push_reason,
+				  desc_info->rxdma_error_code,
+				  desc_info->link_desc.paddr);
+			goto next_entry;
+		}
+
 		/*
 		 * end_of_ppdu is one,
 		 *  a. update ppdu_done stattistics
@@ -800,7 +878,7 @@
 		 */
 		rx_mon_stats->dest_ppdu_done++;
 
-		work_done = dp_rx_mon_reap_status_ring(soc, mac_id,
+		work_done += dp_rx_mon_reap_status_ring(soc, mac_id,
 							quota, desc_info);
 		/* Deliver all MPDUs for a PPDU */
 		if (desc_info->drop_ppdu)
@@ -808,8 +886,8 @@
 		else if (!pdev->hold_mon_dest_ring)
 			dp_rx_monitor_deliver_ppdu(soc, mac_id);
 
+next_entry:
 		hal_srng_dst_get_next(hal_soc, mon_dest_srng);
-		quota -= work_done;
 		break;
 	}
 
@@ -818,7 +896,7 @@
 done1:
 	qdf_spin_unlock_bh(&pdev->mon_lock);
 
-	return quota;
+	return work_done;
 }
 
 /**
diff --git a/dp/wifi3.0/dp_full_mon.h b/dp/wifi3.0/dp_full_mon.h
index defee35..139a075 100644
--- a/dp/wifi3.0/dp_full_mon.h
+++ b/dp/wifi3.0/dp_full_mon.h
@@ -17,6 +17,7 @@
 #ifndef _DP_FULL_MON_H_
 #define _DP_FULL_MON_H_
 
+#define DP_RX_MON_PPDU_ID_WRAP 32535
 /**
  * struct dp_mon_mpdu () - DP Monitor mpdu object
  *
@@ -57,4 +58,20 @@
 	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_rx_fst.c b/dp/wifi3.0/dp_rx_fst.c
index 9911402..8243a05 100644
--- a/dp/wifi3.0/dp_rx_fst.c
+++ b/dp/wifi3.0/dp_rx_fst.c
@@ -303,7 +303,7 @@
 
 	flow.reo_destination_handler = HAL_RX_FSE_REO_DEST_FT;
 	flow.fse_metadata = rx_flow_info->fse_metadata;
-	fse->hal_rx_fse = hal_rx_flow_setup_fse(fst->hal_rx_fst,
+	fse->hal_rx_fse = hal_rx_flow_setup_fse(soc->hal_soc, fst->hal_rx_fst,
 						fse->flow_id, &flow);
 	if (qdf_unlikely(!fse->hal_rx_fse)) {
 		dp_err("Unable to alloc FSE entry");
diff --git a/dp/wifi3.0/dp_rx_mon_feature.c b/dp/wifi3.0/dp_rx_mon_feature.c
index b8a0960..ca93d59 100644
--- a/dp/wifi3.0/dp_rx_mon_feature.c
+++ b/dp/wifi3.0/dp_rx_mon_feature.c
@@ -392,7 +392,7 @@
 		ast_entry = soc->ast_table[ast_index];
 		if (ast_entry) {
 			peer = ast_entry->peer;
-			if (peer && (peer->peer_ids[0] != HTT_INVALID_PEER))
+			if (peer && (peer->peer_id != HTT_INVALID_PEER))
 				return peer->rx_cap_enabled;
 		}
 	}
diff --git a/dp/wifi3.0/dp_rx_tag.c b/dp/wifi3.0/dp_rx_tag.c
index 9eb5e0a..0888686 100644
--- a/dp/wifi3.0/dp_rx_tag.c
+++ b/dp/wifi3.0/dp_rx_tag.c
@@ -135,8 +135,7 @@
 
 	cce_match = true;
 	/* Get the cce_metadata from RX MSDU TLV */
-	cce_metadata = (hal_rx_msdu_cce_metadata_get(soc->hal_soc, rx_tlv_hdr) &
-			RX_MSDU_END_16_CCE_METADATA_MASK);
+	cce_metadata = hal_rx_msdu_cce_metadata_get(soc->hal_soc, rx_tlv_hdr);
 	/*
 	 * Received CCE metadata should be within the
 	 * valid limits
diff --git a/dp/wifi3.0/dp_tx_capture.c b/dp/wifi3.0/dp_tx_capture.c
index 55537a1..a879293 100644
--- a/dp/wifi3.0/dp_tx_capture.c
+++ b/dp/wifi3.0/dp_tx_capture.c
@@ -165,7 +165,7 @@
 
 	stats = &peer->tx_capture.stats;
 	DP_PRINT_STATS(" peer_id[%d] MSDU[S:%u E:%u D:%u F:%u DP:%u X:%u] MPDU[T:%u S:%u R:%u A:%u C:%u ST:%u]",
-			peer->peer_ids[0],
+			peer->peer_id,
 			stats->msdu[PEER_MSDU_SUCC],
 			stats->msdu[PEER_MSDU_ENQ],
 			stats->msdu[PEER_MSDU_DEQ],
@@ -322,7 +322,7 @@
 				if (!msdu_len && !ppdu_len && !tasklet_msdu_len)
 					continue;
 				DP_PRINT_STATS(" peer_id[%d] tid[%d] msdu_comp_q[%d] defer_msdu_q[%d] pending_ppdu_q[%d]",
-					       peer->peer_ids[0], tid,
+					       peer->peer_id, tid,
 					       tasklet_msdu_len,
 					       msdu_len, ppdu_len);
 			}
@@ -2975,7 +2975,7 @@
 			qdf_nbuf_data(ppdu_nbuf);
 
 		usr_idx = dp_tx_find_usr_idx_from_peer_id(ppdu_desc,
-							  peer->peer_ids[0]);
+							  peer->peer_id);
 
 		user = &ppdu_desc->user[usr_idx];
 
@@ -5228,11 +5228,11 @@
 	}
 
 	peer = ast_entry->peer;
-	if (!peer || peer->peer_ids[0] == HTT_INVALID_PEER) {
+	if (!peer || peer->peer_id == HTT_INVALID_PEER) {
 		qdf_spin_unlock_bh(&soc->ast_lock);
 		return QDF_STATUS_E_FAILURE;
 	}
-	peer_id = peer->peer_ids[0];
+	peer_id = peer->peer_id;
 	qdf_spin_unlock_bh(&soc->ast_lock);
 
 	peer = dp_peer_find_by_id(soc, peer_id);
@@ -5367,11 +5367,11 @@
 	}
 
 	peer = ast_entry->peer;
-	if (!peer || peer->peer_ids[0] == HTT_INVALID_PEER) {
+	if (!peer || peer->peer_id == HTT_INVALID_PEER) {
 		qdf_spin_unlock_bh(&soc->ast_lock);
 		return;
 	}
-	peer_id = peer->peer_ids[0];
+	peer_id = peer->peer_id;
 	qdf_spin_unlock_bh(&soc->ast_lock);
 
 	peer = dp_peer_find_by_id(soc, peer_id);
@@ -5635,11 +5635,11 @@
 	}
 
 	peer = ast_entry->peer;
-	if (!peer || peer->peer_ids[0] == HTT_INVALID_PEER) {
+	if (!peer || peer->peer_id == HTT_INVALID_PEER) {
 		qdf_spin_unlock_bh(&soc->ast_lock);
 		return QDF_STATUS_E_FAILURE;
 	}
-	peer_id = peer->peer_ids[0];
+	peer_id = peer->peer_id;
 	qdf_spin_unlock_bh(&soc->ast_lock);
 
 	peer = dp_peer_find_by_id(soc, peer_id);
@@ -5767,7 +5767,7 @@
 	if (!peer)
 		return;
 
-	if (dp_peer_tx_cap_search(pdev, peer->peer_ids[0],
+	if (dp_peer_tx_cap_search(pdev, peer->peer_id,
 				  peer->mac_addr.raw)) {
 		peer->tx_cap_enabled = 1;
 	}
diff --git a/dp/wifi3.0/dp_txrx_wds.c b/dp/wifi3.0/dp_txrx_wds.c
index 4c7c82e..cb16420 100644
--- a/dp/wifi3.0/dp_txrx_wds.c
+++ b/dp/wifi3.0/dp_txrx_wds.c
@@ -958,7 +958,7 @@
 
 	if (soc->cdp_soc.ol_ops->peer_ast_flowid_map) {
 		soc->cdp_soc.ol_ops->peer_ast_flowid_map(
-				soc->ctrl_psoc, peer->peer_ids[0],
+				soc->ctrl_psoc, peer->peer_id,
 				peer->vdev->vdev_id, peer_mac_addr);
 	}
 
diff --git a/dp/wifi3.0/dp_txrx_wds.h b/dp/wifi3.0/dp_txrx_wds.h
index 6df07b0..8aa0207 100644
--- a/dp/wifi3.0/dp_txrx_wds.h
+++ b/dp/wifi3.0/dp_txrx_wds.h
@@ -213,7 +213,7 @@
 	if (ast->is_mapped && (ast->ast_idx == sa_idx))
 		ast->is_active = TRUE;
 
-	if (sa_sw_peer_id != ta_peer->peer_ids[0]) {
+	if (sa_sw_peer_id != ta_peer->peer_id) {
 		sa_peer = ast->peer;
 
 		if ((ast->type != CDP_TXRX_AST_TYPE_STATIC) &&
diff --git a/qca_multi_link/inc/qca_multi_link.h b/qca_multi_link/inc/qca_multi_link.h
index b997b32..f9bf565 100644
--- a/qca_multi_link/inc/qca_multi_link.h
+++ b/qca_multi_link/inc/qca_multi_link.h
@@ -23,6 +23,7 @@
 #include <qdf_util.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/version.h>
 #include <linux/wireless.h>
 #include <net/cfg80211.h>
 #include <br_private.h>
diff --git a/qca_multi_link/src/qca_multi_link_tbl.c b/qca_multi_link/src/qca_multi_link_tbl.c
index 7d7d98e..634e5a3 100644
--- a/qca_multi_link/src/qca_multi_link_tbl.c
+++ b/qca_multi_link/src/qca_multi_link_tbl.c
@@ -45,11 +45,22 @@
 	 */
 	rcu_read_lock();
 	for (i = 0; i < BR_HASH_SIZE ; i++) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 24)
 		hlist_for_each_entry_rcu(search_fdb, &p->br->hash[i], hlist) {
+#else
+		hlist_for_each_entry_rcu(search_fdb, &p->br->fdb_list,
+					 fdb_node) {
+#endif
 			ndev = search_fdb->dst ? search_fdb->dst->dev : NULL;
 			wdev = ndev ? ndev->ieee80211_ptr : NULL;
 			if (!wdev && ndev) {
-				memcpy(qfdb->qal_mac_addr, search_fdb->addr.addr, 6);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 24)
+				memcpy(qfdb->qal_mac_addr,
+				       search_fdb->addr.addr, 6);
+#else
+				memcpy(qfdb->qal_mac_addr,
+				       search_fdb->key.addr.addr, 6);
+#endif
 				qfdb->qal_fdb_dev = ndev;
 				qfdb->qal_fdb_is_local =  search_fdb->is_local;
 				num_of_entries++;
@@ -89,7 +100,12 @@
 
 	rcu_read_lock();
 	for (i = 0; i < BR_HASH_SIZE; i++) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 24)
 		hlist_for_each_entry_rcu(search_fdb, &p->br->hash[i], hlist) {
+#else
+		hlist_for_each_entry_rcu(search_fdb, &p->br->fdb_list,
+					 fdb_node) {
+#endif
 			if (!search_fdb->is_local)
 				continue;
 
@@ -112,8 +128,14 @@
 
 QDF_STATUS qca_multi_link_tbl_delete_entry(struct net_device *net_dev, uint8_t *addr)
 {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 24)
 	int status;
+#endif
 	struct net_bridge_fdb_entry *fdb_entry = NULL;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 24)
+	struct net_bridge_port *fdb_port = NULL;
+	struct net_bridge *br = NULL;
+#endif
 
 	fdb_entry = br_fdb_has_entry(net_dev, addr, 0);
 	if (!fdb_entry) {
@@ -124,10 +146,25 @@
 		return QDF_STATUS_SUCCESS;
 	}
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 24)
+	fdb_port = br_port_get_rcu(net_dev);
+	if (!fdb_port) {
+		qdf_err("fdb port is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	br = fdb_port->br;
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 24)
 	status = br_fdb_delete_by_netdev(net_dev, addr, 0);
 	if (status < 0) {
 		return QDF_STATUS_E_FAILURE;
 	}
+#else
+	/* Use 5.4-specific API */
+	qdf_info("Needs alternative implementation");
+#endif
 	return QDF_STATUS_SUCCESS;
 }
 
diff --git a/tools/linux/cfg80211_ven_cmd.h b/tools/linux/cfg80211_ven_cmd.h
index c02ef39..bb8c7d5 100644
--- a/tools/linux/cfg80211_ven_cmd.h
+++ b/tools/linux/cfg80211_ven_cmd.h
@@ -1190,6 +1190,8 @@
 	OL_ATH_PARAM_NXT_RDR_FREQ = 444,
 	/* set the flag for a radio with no backhaul */
 	OL_ATH_PARAM_NO_BACKHAUL_RADIO = 445,
+	/* MAX_PHY feature flag per PDEV */
+	OL_ATH_PARAM_RPT_MAX_PHY = 446,
 
 };
 
@@ -1207,7 +1209,7 @@
 	{"get_mcastkeylen",     IEEE80211_PARAM_MCASTKEYLEN, GET_PARAM, 0},
 	{"ucastciphers",        IEEE80211_PARAM_UCASTCIPHERS, SET_PARAM, 1},
 	{"get_uciphers",        IEEE80211_PARAM_UCASTCIPHERS, GET_PARAM, 0},
-	{"ucastciphers",        IEEE80211_PARAM_UCASTCIPHER, SET_PARAM, 1},
+	{"ucastcipher",         IEEE80211_PARAM_UCASTCIPHER, SET_PARAM, 1},
 	{"get_ucastcipher",     IEEE80211_PARAM_UCASTCIPHER, GET_PARAM, 0},
 	{"ucastkeylen",         IEEE80211_PARAM_UCASTKEYLEN, SET_PARAM, 1},
 	{"get_ucastkeylen",     IEEE80211_PARAM_UCASTKEYLEN, GET_PARAM, 0},
@@ -1329,7 +1331,6 @@
 	{"get_hbrtimer",        IEEE80211_PARAM_HBR_TIMER, GET_PARAM, 0},
 	{"get_hbrstate",        IEEE80211_PARAM_HBR_STATE, GET_PARAM, 0},
 	{"chextoffset",         IEEE80211_PARAM_CHEXTOFFSET, SET_PARAM, 1},
-	{"get_chextoffset",     IEEE80211_PARAM_CHEXTOFFSET, GET_PARAM, 0},
 	{"chscaninit",          IEEE80211_PARAM_CHSCANINIT, SET_PARAM, 1},
 	{"get_chscaninit",      IEEE80211_PARAM_CHSCANINIT, GET_PARAM, 0},
 	{"ht40intol",           IEEE80211_PARAM_HT40_INTOLERANT, SET_PARAM, 1},
@@ -1438,8 +1439,6 @@
 	{"g_oce",               IEEE80211_PARAM_OCE, GET_PARAM, 0},
 	{"oce_asoc_rej",        IEEE80211_PARAM_OCE_ASSOC_REJECT, SET_PARAM, 1},
 	{"g_oce_asoc_rej",      IEEE80211_PARAM_OCE_ASSOC_REJECT, GET_PARAM, 0},
-	{"oce_asoc_rssi",       IEEE80211_PARAM_OCE_ASSOC_MIN_RSSI, SET_PARAM, 1},
-	{"g_oce_asoc_rssi",     IEEE80211_PARAM_OCE_ASSOC_MIN_RSSI, GET_PARAM, 0},
 	{"oce_asoc_dly",        IEEE80211_PARAM_OCE_ASSOC_RETRY_DELAY, SET_PARAM, 1},
 	{"g_oce_asoc_dly",      IEEE80211_PARAM_OCE_ASSOC_RETRY_DELAY, GET_PARAM, 0},
 	{"oce_wan_mtr",         IEEE80211_PARAM_OCE_WAN_METRICS, SET_PARAM, 2},
@@ -1455,8 +1454,9 @@
 	{"rnr_fd",              IEEE80211_PARAM_RNR_FD, SET_PARAM, 1},
 	{"g_rnr_fd",            IEEE80211_PARAM_RNR_FD, GET_PARAM, 0},
 	{"rnr_tbtt",            IEEE80211_PARAM_RNR_TBTT, SET_PARAM, 1},
-	{"apchanrpt",           IEEE80211_PARAM_RNR_TBTT, GET_PARAM, 0},
-	{"g_apchanrpt",         IEEE80211_PARAM_AP_CHAN_RPT, SET_PARAM, 1},
+	{"g_rnr_tbtt",          IEEE80211_PARAM_RNR_TBTT, GET_PARAM, 0},
+	{"apchanrpt",           IEEE80211_PARAM_AP_CHAN_RPT, SET_PARAM, 1},
+	{"g_apchanrpt",         IEEE80211_PARAM_AP_CHAN_RPT, GET_PARAM, 0},
 	{"mgmt_rate",           IEEE80211_PARAM_MGMT_RATE, SET_PARAM, 1},
 	{"g_mgmt_rate",         IEEE80211_PARAM_MGMT_RATE, GET_PARAM, 0},
 	{"rrm",                 IEEE80211_PARAM_RRM_CAP, SET_PARAM, 1},
@@ -1492,19 +1492,19 @@
 	{"get_ccmpSwSelEn",     IEEE80211_PARAM_CCMPSW_ENCDEC, GET_PARAM, 0},
 	{"periodicScan",        IEEE80211_PARAM_PERIODIC_SCAN, SET_PARAM, 1},
 	{"g_periodicScan",      IEEE80211_PARAM_PERIODIC_SCAN, GET_PARAM, 0},
+	{"csa2g",               IEEE80211_PARAM_2G_CSA, SET_PARAM, 1},
+	{"get_csa2g",           IEEE80211_PARAM_2G_CSA, GET_PARAM, 0},
 	{"wapi_rkupkt",         IEEE80211_PARAM_WAPIREKEY_USK, SET_PARAM, 1},
 	{"get_wapi_rkupkt",     IEEE80211_PARAM_WAPIREKEY_USK, GET_PARAM, 0},
 	{"wapi_rkmpkt",         IEEE80211_PARAM_WAPIREKEY_MSK, SET_PARAM, 1},
 	{"get_wapi_rkmpkt",     IEEE80211_PARAM_WAPIREKEY_MSK, GET_PARAM, 0},
-	{"csa2g",               IEEE80211_PARAM_2G_CSA, SET_PARAM, 1},
-	{"get_csa2g",           IEEE80211_PARAM_2G_CSA, GET_PARAM, 0},
 	{"wapi_rkupdate",       IEEE80211_PARAM_WAPIREKEY_UPDATE, SET_PARAM, 1},
 	{"wdsaddr",             IEEE80211_PARAM_ADD_WDS_ADDR, SET_PARAM, 1},
 #if UMAC_SUPPORT_VI_DBG
 	{"dbgcfg",              IEEE80211_PARAM_DBG_CFG, SET_PARAM, 1},
 	{"getdbgcfg",           IEEE80211_PARAM_DBG_CFG, GET_PARAM, 0},
-	{"dbgrestart",          IEEE80211_PARAM_DBG_NUM_STREAMS, SET_PARAM, 1},
-	{"getdbgrestart",       IEEE80211_PARAM_DBG_NUM_STREAMS, GET_PARAM, 0},
+	{"dbgrestart",          IEEE80211_PARAM_RESTART, SET_PARAM, 1},
+	{"getdbgrestart",       IEEE80211_PARAM_RESTART, GET_PARAM, 0},
 	{"rxdropstats",         IEEE80211_PARAM_RXDROP_STATUS, SET_PARAM, 1},
 	{"getrxdropstats",      IEEE80211_PARAM_RXDROP_STATUS, GET_PARAM, 0},
 #endif
@@ -1640,8 +1640,8 @@
 	{"get_vhtstscap",       IEEE80211_PARAM_VHT_STS_CAP, GET_PARAM, 0},
 	{"vhtsounddim",         IEEE80211_PARAM_VHT_SOUNDING_DIM, SET_PARAM, 1},
 	{"get_vhtsounddim",     IEEE80211_PARAM_VHT_SOUNDING_DIM, GET_PARAM, 0},
-	{"vhtsubfee",           IEEE80211_PARAM_VHT_MUBFEE, SET_PARAM, 1},
-	{"get_vhtsubfee",       IEEE80211_PARAM_VHT_MUBFEE, GET_PARAM, 0},
+	{"vhtsubfee",           IEEE80211_PARAM_VHT_SUBFEE, SET_PARAM, 1},
+	{"get_vhtsubfee",       IEEE80211_PARAM_VHT_SUBFEE, GET_PARAM, 0},
 	{"vhtmubfee",           IEEE80211_PARAM_VHT_MUBFEE, SET_PARAM, 1},
 	{"get_vhtmubfee",       IEEE80211_PARAM_VHT_MUBFEE, GET_PARAM, 0},
 	{"vhtsubfer",           IEEE80211_PARAM_VHT_SUBFER, SET_PARAM, 1},
@@ -1719,9 +1719,7 @@
 	{"get_blbwnssmap",      IEEE80211_DISABLE_STA_BWNSS_ADV, GET_PARAM, 0},
 	{"neighbourfilter",     IEEE80211_PARAM_RX_FILTER_NEIGHBOUR_PEERS_MONITOR,
 		SET_PARAM, 1},
-#if ATH_DATA_RX_INFO_EN
-	{"get_whc_wds",         IEEE80211_PARAM_RXINFO_PERPKT, GET_PARAM, 0},
-#endif
+	{"get_whc_wds",         IEEE80211_PARAM_WHC_APINFO_WDS, GET_PARAM, 0},
 	{"set_whc_dist",        IEEE80211_PARAM_WHC_APINFO_ROOT_DIST, SET_PARAM, 1},
 	{"get_whc_dist",        IEEE80211_PARAM_WHC_APINFO_ROOT_DIST, GET_PARAM, 0},
 	{"assocwar160",         IEEE80211_PARAM_CONFIG_ASSOC_WAR_160W, SET_PARAM, 1},
@@ -1841,7 +1839,7 @@
 	{"g_db_timeout",        IEEE80211_PARAM_DBEACON_TIMEOUT, GET_PARAM, 0},
 #endif
 	{"s_txpow_mgmt",        IEEE80211_PARAM_TXPOW_MGMT, SET_PARAM, 2},
-	{"g_txpow_mgmt",        IEEE80211_PARAM_TXPOW_MGMT, GET_PARAM, 0},
+	{"g_txpow_mgmt",        IEEE80211_PARAM_TXPOW_MGMT, GET_PARAM, 1},
 	{"tx_capture",          IEEE80211_PARAM_CONFIG_TX_CAPTURE, SET_PARAM, 1},
 	{"g_tx_capture",        IEEE80211_PARAM_CONFIG_TX_CAPTURE, GET_PARAM, 0},
 	{"backhaul",            IEEE80211_PARAM_BACKHAUL, SET_PARAM, 1},
@@ -1934,7 +1932,7 @@
 	{"enable_11v_dms",      IEEE80211_PARAM_DMS_AMSDU_WAR, SET_PARAM, 1},
 	{"g_enable_11v_dms",    IEEE80211_PARAM_DMS_AMSDU_WAR, GET_PARAM, 0},
 	{"s_txpow",             IEEE80211_PARAM_TXPOW, SET_PARAM, 2},
-	{"g_txpow",             IEEE80211_PARAM_TXPOW, GET_PARAM, 0},
+	{"g_txpow",             IEEE80211_PARAM_TXPOW, GET_PARAM, 1},
 	{"ul_hyst",             IEEE80211_PARAM_BEST_UL_HYST, SET_PARAM, 1},
 	{"g_ul_hyst",           IEEE80211_PARAM_BEST_UL_HYST, GET_PARAM, 0},
 	{"he_txmcsmap",         IEEE80211_PARAM_HE_TX_MCSMAP, SET_PARAM, 1},
@@ -2014,7 +2012,7 @@
 	{"whc_mixedbh_bh_type", IEEE80211_PARAM_WHC_BACKHAUL_TYPE, SET_PARAM, 1},
 	{"he_bsr_supp",         IEEE80211_PARAM_HE_BSR_SUPPORT, SET_PARAM, 1},
 	{"get_he_bsr_supp",     IEEE80211_PARAM_HE_BSR_SUPPORT, GET_PARAM, 0},
-	{"display_me_info",     IEEE80211_PARAM_DUMP_RA_TABLE, SET_PARAM, 1},
+	{"display_me_info",     IEEE80211_PARAM_DUMP_RA_TABLE, GET_PARAM, 0},
 	{"set_obss_ru_tolerance_time",  IEEE80211_PARAM_OBSS_NB_RU_TOLERANCE_TIME,
 		SET_PARAM, 1},
 	{"get_obss_ru_tolerance_time",  IEEE80211_PARAM_OBSS_NB_RU_TOLERANCE_TIME,
@@ -2047,7 +2045,7 @@
 	{"tx_lat_capture",      IEEE80211_PARAM_CONFIG_CAPTURE_LATENCY_ENABLE,
 		SET_PARAM, 1},
 	{"g_tx_lat_cptr",       IEEE80211_PARAM_CONFIG_CAPTURE_LATENCY_ENABLE,
-		SET_PARAM, 1},
+		GET_PARAM, 1},
 	{"get_ru26_tolerance",  IEEE80211_PARAM_GET_RU26_TOLERANCE, GET_PARAM, 0},
 	{"get_whc_ul_snr",      IEEE80211_PARAM_WHC_APINFO_UPLINK_SNR, GET_PARAM, 0},
 	{"set_dpp_mode",        IEEE80211_PARAM_DPP_VAP_MODE, SET_PARAM, 1},
@@ -2143,8 +2141,6 @@
 	{"he_dlofdma_bf",       IEEE80211_PARAM_HE_DL_MU_OFDMA_BFER, SET_PARAM, 1},
 	{"g_he_dlofdma_bf",     IEEE80211_PARAM_HE_DL_MU_OFDMA_BFER, GET_PARAM, 0},
 	{"sendprobereq",        IEEE80211_PARAM_SEND_PROBE_REQ, SET_PARAM, 1},
-	{"min_asoc_rssi",       IEEE80211_PARAM_ASSOC_MIN_RSSI, SET_PARAM, 1},
-	{"g_min_asoc_rssi",     IEEE80211_PARAM_ASSOC_MIN_RSSI, GET_PARAM, 0},
 	{"oce_txpower",         IEEE80211_PARAM_OCE_TX_POWER, SET_PARAM, 2},
 	{"g_oce_txpower",       IEEE80211_PARAM_OCE_TX_POWER, GET_PARAM, 0},
 	{"oce_subnet_id",       IEEE80211_PARAM_OCE_IP_SUBNET_ID, SET_PARAM, 2},
@@ -2213,12 +2209,10 @@
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_BCN_BURST, SET_PARAM, 1},
 	{"get_bcnburst",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_BCN_BURST, GET_PARAM, 0},
-#if UMAC_SUPPORT_PERIODIC_PERFSTATS
 	{"dcs_enable",
-		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_PRDPERFSTAT_THRPUT_ENAB, SET_PARAM, 1},
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_DCS, SET_PARAM, 1},
 	{"get_dcs_enable",
-		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_PRDPERFSTAT_THRPUT_ENAB, GET_PARAM, 0},
-#endif
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_DCS, GET_PARAM, 0},
 	{"get_total_PER",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_TOTAL_PER, GET_PARAM, 0},
 	{"setctsrate",
@@ -2546,7 +2540,7 @@
 	{"arp_dbg_dstaddr",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_DBG_ARP_DST_ADDR, SET_PARAM, 1},
 	{"arp_dbg_conf",
-		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_DBG_ARP_DST_ADDR, SET_PARAM, 1},
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_ARP_DBG_CONF, SET_PARAM, 1},
 	{"g_arp_dbg_conf",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_ARP_DBG_CONF, GET_PARAM, 0},
 	{"st_ht_noamsdu",
@@ -2730,7 +2724,7 @@
 	{"get_reo_dest",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_PDEV_TO_REO_DEST, GET_PARAM, 0},
 	{"dump_chmsk_tbl",
-		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_DUMP_CHAINMASK_TABLES, SET_PARAM, 1},
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_DUMP_CHAINMASK_TABLES, GET_PARAM, 0},
 	{"print_obj_refs",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_DUMP_OBJECTS, SET_PARAM, 1},
 	{"acs_srloadvar",
@@ -2749,8 +2743,6 @@
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_ICM_ACTIVE, SET_PARAM, 1},
 	{"get_icm_active",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_ICM_ACTIVE, GET_PARAM, 0},
-	{"get_nominal_noisefloor",
-		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_NOMINAL_NOISEFLOOR, GET_PARAM, 0},
 	{"acs_rank_en",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_ACS_RANK, SET_PARAM, 1},
 	{"g_acs_rank_en",
@@ -3013,6 +3005,10 @@
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_NXT_RDR_FREQ, SET_PARAM, 1},
 	{"getNxtRadarFreq",
 		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_NXT_RDR_FREQ, GET_PARAM, 0},
+	{"rpt_max_phy",
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_RPT_MAX_PHY, SET_PARAM, 1},
+	{"g_rpt_max_phy",
+		OL_ATH_PARAM_SHIFT | OL_ATH_PARAM_RPT_MAX_PHY, GET_PARAM, 0},
 	{"setCountryID",
 		OL_SPECIAL_PARAM_SHIFT | OL_SPECIAL_PARAM_COUNTRY_ID, SET_PARAM, 1},
 	{"getCountryID",
diff --git a/tools/linux/cfr_test_app.c b/tools/linux/cfr_test_app.c
index 1a9dd2b..7224e66 100644
--- a/tools/linux/cfr_test_app.c
+++ b/tools/linux/cfr_test_app.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-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
@@ -40,7 +40,7 @@
 #include <signal.h>
 
 #define CFR_DUMP_STREAMFS_FILE "/sys/kernel/debug/qdf/cfr%s/cfr_dump0"
-#define CFR_DUMP_FILE "/tmp/cfr_dump_%s.bin"
+#define CFR_DUMP_FILE "/tmp/cfr_dump_%s_%s.bin"
 
 #define MAX_FILE_SIZE          (8 * 1024 * 1024)
 #define MAX_CAPTURE_SIZE       (4096)
@@ -122,7 +122,7 @@
 	tm_val = localtime(&curtime);
 	if (tm_val) {
 		strftime(time, 50, "%Y_%m_%d_%T", tm_val);
-		snprintf(filename, sizeof(filename), CFR_DUMP_FILE, time);
+		snprintf(filename, sizeof(filename), CFR_DUMP_FILE, iface, time);
 		fd = open(filename, O_WRONLY | O_CREAT);
 	} else {
 		perror("Unable to get time value to generate filename \n");
diff --git a/umac/dfs/core/src/misc/dfs_zero_cac.c b/umac/dfs/core/src/misc/dfs_zero_cac.c
index d35435b..939c7cb 100644
--- a/umac/dfs/core/src/misc/dfs_zero_cac.c
+++ b/umac/dfs/core/src/misc/dfs_zero_cac.c
@@ -1953,23 +1953,104 @@
 }
 #endif
 
+#ifdef QCA_SUPPORT_AGILE_DFS
+#ifdef CONFIG_CHAN_FREQ_API
+/* Checks the Host side agile configurations. ie if agile channel
+ * is configured as 5730MHz and the agile channel width is 80P80/165MHz.
+ */
+#define IS_HOST_AGILE_CURCHAN_165MHZ(_x) \
+	((_x)->dfs_agile_precac_freq_mhz == \
+	 RESTRICTED_80P80_CHAN_CENTER_FREQ) && \
+	((_x)->dfs_precac_chwidth == CH_WIDTH_80P80MHZ)
+
+/* Checks if the FW Agile operation was on the restricited 80P80MHz,
+ * by comparing the center frequency 1 with 5690MHz, center frequency 2
+ * with 5775MHz and the channel width was 80P80/165MHz.
+ */
+#define IS_OCAC_EVENT_ON_165_MHZ_CHAN(_x, _y, _z) \
+	((_x) == RESTRICTED_80P80_LEFT_80_CENTER_FREQ) && \
+	((_y) == RESTRICTED_80P80_RIGHT_80_CENTER_FREQ) && \
+	((_z) == CH_WIDTH_80P80MHZ)
+
+/*
+ * dfs_is_ocac_complete_event_for_cur_agile_chan() - Check if the OCAC
+ * completion event from FW is received for the currently configured agile
+ * channel in host.
+ *
+ * @dfs: Pointer to dfs structure.
+ * @center_freq_mhz1: Center frequency of the band when the precac width is
+ * 20/40/80/160MHz and center frequency of the left 80MHz in case of restricted
+ * 80P80/165MHz.
+ * @center_freq_mhz2: Center frequency of the right 80MHz in case of restricted
+ * 80P80/165MHz. It is zero for other channel widths.
+ * @chwidth: Agile channel width for which the completion event is received.
+ *
+ * return: True if the channel on which OCAC completion event received is same
+ * as currently configured agile channel in host. False otherwise.
+ */
+static bool
+dfs_is_ocac_complete_event_for_cur_agile_chan(struct wlan_dfs *dfs,
+					      uint32_t center_freq_mhz1,
+					      uint32_t center_freq_mhz2,
+					      enum phy_ch_width chwidth)
+{
+    if (IS_HOST_AGILE_CURCHAN_165MHZ(dfs) &&
+	IS_OCAC_EVENT_ON_165_MHZ_CHAN(center_freq_mhz1,
+				      center_freq_mhz2,
+				      chwidth))
+	return true;
+    else if (dfs->dfs_agile_precac_freq_mhz == center_freq_mhz1)
+	return true;
+    else
+	return false;
+}
+
 /*
  * dfs_process_ocac_complete() - Process OCAC Complete eventid.
  * @pdev: Pointer to wlan_objmgr_pdev.
  * @ocac_status: OCAC Status.
- * @center_freq_mhz: Center frequency in MHZ.
+ * @center_freq_mhz1: Center frequency of the band when the precac width is
+ * 20/40/80/160MHz and center frequency of the left 80MHz in case of restricted
+ * 80P80/165MHz.
+ * @center_freq_mhz2: Center frequency of the right 80MHz in case of restricted
+ * 80P80/165MHz. It is zero for other channel widths.
+ * @chwidth: Agile channel width for which the completion event is received.
  */
-#ifdef QCA_SUPPORT_AGILE_DFS
-#ifdef CONFIG_CHAN_FREQ_API
 void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev,
 			       uint32_t ocac_status,
-			       uint32_t center_freq_mhz)
+			       uint32_t center_freq_mhz1,
+			       uint32_t center_freq_mhz2,
+			       enum phy_ch_width chwidth)
 {
 	struct wlan_dfs *dfs = NULL;
 	struct dfs_agile_cac_params adfs_param;
 
 	dfs = wlan_pdev_get_dfs_obj(pdev);
 
+	/* When the FW sends a delayed OCAC completion status, Host might
+	 * have changed the precac channel already before an OCAC
+	 * completion event is received. So the OCAC completion status
+	 * should be validated if it is on the currently configured agile
+	 * channel.
+	 */
+
+	/* Assume the previous agile channel was 64 (20Mhz) and current
+	 * agile channel is 100(20Mhz), if the event from the FW is for
+	 * previously configured agile channel 64(20Mhz) then Host ignores
+	 * the event.
+	 */
+	if (!dfs_is_ocac_complete_event_for_cur_agile_chan(dfs,
+							  center_freq_mhz1,
+							  center_freq_mhz2,
+							  chwidth)) {
+	    dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
+		    "OCAC completion event is received on a different channel %d %d that is not the current Agile channel %d",
+		    center_freq_mhz1,
+		    center_freq_mhz2,
+		    dfs->dfs_agile_precac_freq_mhz);
+	    return;
+	}
+
 	/* STOP TIMER irrespective of status */
 	utils_dfs_cancel_precac_timer(pdev);
 	if (ocac_status == OCAC_RESET) {
@@ -1981,13 +2062,15 @@
 			  "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_mhz);
+			  "PreCAC timer Completed for agile freq: %d %d",
+			  center_freq_mhz1,
+			  center_freq_mhz2);
 		/*
 		 * TRIGGER agile precac timer with 0sec timeout
 		 * with ocac_status 0 for old pdev
 		 */
-		adfs_param.precac_center_freq_1 = center_freq_mhz;
+		adfs_param.precac_center_freq_1 = center_freq_mhz1;
+		adfs_param.precac_center_freq_2 = center_freq_mhz2;
 		adfs_param.precac_chwidth = dfs->dfs_precac_chwidth;
 		dfs_start_agile_precac_timer(dfs,
 					     ocac_status,
@@ -4868,7 +4951,9 @@
 	bool rcac_enabled = false;
 
 	dfsdomain = utils_get_dfsdomain(dfs->dfs_pdev_obj);
-	if ((dfsdomain == DFS_FCC_REGION || dfsdomain == DFS_MKK_REGION) &&
+	if ((dfsdomain == DFS_FCC_REGION ||
+	     dfsdomain == DFS_MKK_REGION ||
+	     dfsdomain == DFS_MKKN_REGION) &&
 	    dfs->dfs_agile_rcac_ucfg && dfs->dfs_fw_adfs_support_non_160)
 	    rcac_enabled = true;
 
diff --git a/wmi/src/wmi_unified_ap_tlv.c b/wmi/src/wmi_unified_ap_tlv.c
index a1c7049..426599d 100644
--- a/wmi/src/wmi_unified_ap_tlv.c
+++ b/wmi/src/wmi_unified_ap_tlv.c
@@ -1703,7 +1703,8 @@
 		WMITLV_TAG_STRUC_wmi_pdev_update_pkt_routing_cmd_fixed_param,
 		WMITLV_GET_STRUCT_TLVLEN(
 	wmi_pdev_update_pkt_routing_cmd_fixed_param));
-	cmd->pdev_id = param->pdev_id;
+	cmd->pdev_id = wmi_hdl->ops->convert_pdev_id_host_to_target(wmi_hdl,
+							param->pdev_id);
 	cmd->op_code = (A_UINT32) param->op_code;
 	cmd->routing_type_bitmap = param->routing_type_bitmap;
 	cmd->dest_ring = param->dest_ring;
@@ -2437,7 +2438,7 @@
 {
 	wmi_buf_t buf;
 	wmi_peer_chan_width_switch_cmd_fixed_param *cmd;
-	int32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
+	int32_t len;
 	uint32_t max_peers_per_command, max_peers_per_buf;
 	wmi_chan_width_peer_list *cmd_peer_list;
 	int16_t pending_peers = param->num_peers;
@@ -2464,13 +2465,14 @@
 	WMI_LOGD("Setting peer limit as %u", max_peers_per_command);
 
 	while (pending_peers > 0) {
+		len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
 		if (pending_peers >= max_peers_per_command) {
 			len += (max_peers_per_command * sizeof(*cmd_peer_list));
 		} else {
 			len += (pending_peers * sizeof(*cmd_peer_list));
 		}
 
-                buf = wmi_buf_alloc(wmi_handle, len);
+		buf = wmi_buf_alloc(wmi_handle, len);
 		if (!buf) {
 			WMI_LOGE("wmi_buf_alloc failed");
 			return QDF_STATUS_E_FAILURE;
@@ -2571,6 +2573,7 @@
 		struct rnr_tbtt_multisoc_sync_param *param)
 {
 	wmi_pdev_tbtt_offset_sync_cmd_fixed_param *tbtt_sync_cmd;
+	struct rnr_bss_tbtt_info_param *tmp_bss;
 	wmi_buf_t buf;
 	wmi_pdev_rnr_bss_tbtt_info *bss_tbtt_info;
 	int32_t len = 0;
@@ -2591,6 +2594,7 @@
 		WMI_LOGP("%s: cmd_type: %d invalid", __func__, param->cmd_type);
 		return QDF_STATUS_E_FAILURE;
 	}
+	tmp_bss = param->rnr_bss_tbtt;
 	buf = wmi_buf_alloc(wmi, len);
 	if (!buf) {
 		WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
@@ -2618,24 +2622,24 @@
 			WMITLV_SET_HDR(&bss_tbtt_info->tlv_header,
 				WMITLV_TAG_STRUC_wmi_pdev_rnr_bss_tbtt_info,
 				WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_rnr_bss_tbtt_info));
-			WMI_CHAR_ARRAY_TO_MAC_ADDR(param->rnr_bss_tbtt->bss_mac,
+			WMI_CHAR_ARRAY_TO_MAC_ADDR(tmp_bss->bss_mac,
 					&bss_tbtt_info->bss_mac);
 			bss_tbtt_info->beacon_intval =
-				param->rnr_bss_tbtt->beacon_intval;
-			bss_tbtt_info->opclass = param->rnr_bss_tbtt->opclass;
+				tmp_bss->beacon_intval;
+			bss_tbtt_info->opclass = tmp_bss->opclass;
 			bss_tbtt_info->chan_idx =
-				param->rnr_bss_tbtt->chan_idx;
+				tmp_bss->chan_idx;
 			bss_tbtt_info->next_qtime_tbtt_high =
-				param->rnr_bss_tbtt->next_qtime_tbtt_high;
+				tmp_bss->next_qtime_tbtt_high;
 			bss_tbtt_info->next_qtime_tbtt_low =
-				param->rnr_bss_tbtt->next_qtime_tbtt_low;
+				tmp_bss->next_qtime_tbtt_low;
 			QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
 				  "Beacon Intval: %d, Chan: %d, opclass: %d",
 				  bss_tbtt_info->beacon_intval,
 				  bss_tbtt_info->chan_idx,
 				  bss_tbtt_info->opclass);
 			bss_tbtt_info++;
-			param->rnr_bss_tbtt++;
+			tmp_bss++;
 		}
 	}
 	QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c
index 75845fd..d2dc84b 100644
--- a/wmi/src/wmi_unified_non_tlv.c
+++ b/wmi/src/wmi_unified_non_tlv.c
@@ -1092,7 +1092,7 @@
 {
 	wmi_buf_t buf;
 	wmi_peer_chan_width_switch_cmd *cmd;
-	int len = sizeof(*cmd);
+	int len;
 	int max_peers_per_command;
 	struct chan_width_peer_list *cmd_peer_list;
 	int pending_peers = param->num_peers;
@@ -1104,13 +1104,14 @@
 				 sizeof(*cmd)) / sizeof(*cmd_peer_list);
 
 	while (pending_peers > 0) {
+		len = sizeof(*cmd);
 		if (pending_peers >= max_peers_per_command) {
 			len += (max_peers_per_command * sizeof(*cmd_peer_list));
 		} else {
 			len += (pending_peers * sizeof(*cmd_peer_list));
 		}
 
-                buf = wmi_buf_alloc(wmi_handle, len);
+		buf = wmi_buf_alloc(wmi_handle, len);
 		if (!buf) {
 			WMI_LOGE("wmi_buf_alloc failed");
 			return QDF_STATUS_E_FAILURE;