Эх сурвалжийг харах

qcacmn: add module id for peer reference

Add support to get the peer reference with module id

To help debug the peer reference related issues

Change-Id: Ie20c7e710b9784b52f2e0f3d7488509282528a00
Chaithanya Garrepalli 4 жил өмнө
parent
commit
fdc6a808ae

+ 81 - 34
dp/wifi3.0/dp_htt.c

@@ -70,6 +70,33 @@ dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap)
 }
 
 #ifdef FEATURE_PERPKT_INFO
+/*
+ * dp_peer_find_by_id_valid - check if peer exists for given id
+ * @soc: core DP soc context
+ * @peer_id: peer id from peer object can be retrieved
+ *
+ * Return: true if peer exists of false otherwise
+ */
+
+static
+bool dp_peer_find_by_id_valid(struct dp_soc *soc, uint16_t peer_id)
+{
+	struct dp_peer *peer = dp_peer_get_ref_by_id(soc, peer_id,
+						     DP_MOD_ID_HTT);
+
+	if (peer) {
+		/*
+		 * Decrement the peer ref which is taken as part of
+		 * dp_peer_get_ref_by_id if PEER_LOCK_REF_PROTECT is enabled
+		 */
+		dp_peer_unref_delete(peer, DP_MOD_ID_HTT);
+
+		return true;
+	}
+
+	return false;
+}
+
 /*
  * dp_peer_copy_delay_stats() - copy ppdu stats to peer delayed stats.
  * @peer: Datapath peer handle
@@ -2395,7 +2422,8 @@ static void dp_process_ppdu_stats_user_common_tlv(
 		qdf_mem_copy(ppdu_user_desc->mac_addr, vdev->mac_addr.raw,
 			     QDF_MAC_ADDR_SIZE);
 	} else {
-		peer = dp_peer_find_by_id(pdev->soc, peer_id);
+		peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
+					     DP_MOD_ID_TX_PPDU_STATS);
 		if (!peer) {
 			/*
 			 * fw sends peer_id which is about to removed but
@@ -2415,7 +2443,7 @@ static void dp_process_ppdu_stats_user_common_tlv(
 		}
 		qdf_mem_copy(ppdu_user_desc->mac_addr,
 			     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 	}
 }
 
@@ -2459,13 +2487,14 @@ static void dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev,
 		qdf_mem_copy(ppdu_user_desc->mac_addr, vdev->mac_addr.raw,
 			     QDF_MAC_ADDR_SIZE);
 	} else {
-		peer = dp_peer_find_by_id(pdev->soc, peer_id);
+		peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
+					     DP_MOD_ID_TX_PPDU_STATS);
 		if (peer) {
 			ppdu_desc->vdev_id = peer->vdev->vdev_id;
 			qdf_mem_copy(ppdu_user_desc->mac_addr,
 				     peer->mac_addr.raw,
 				     QDF_MAC_ADDR_SIZE);
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 		}
 	}
 
@@ -2549,7 +2578,9 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
 	peer_id =
 	HTT_PPDU_STATS_ENQ_MPDU_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
+				     DP_MOD_ID_TX_PPDU_STATS);
+
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
@@ -2557,7 +2588,7 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
 		ppdu_desc->vdev_id = peer->vdev->vdev_id;
 		qdf_mem_copy(ppdu_user_desc->mac_addr,
 			     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 	}
 	ppdu_user_desc->peer_id = peer_id;
 
@@ -2602,7 +2633,8 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
 	peer_id =
 	HTT_PPDU_STATS_ENQ_MPDU_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
+				     DP_MOD_ID_TX_PPDU_STATS);
 
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
@@ -2611,7 +2643,7 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
 		ppdu_desc->vdev_id = peer->vdev->vdev_id;
 		qdf_mem_copy(ppdu_user_desc->mac_addr,
 			     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 	}
 	ppdu_user_desc->peer_id = peer_id;
 
@@ -2654,7 +2686,9 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv(
 	peer_id =
 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
+				     DP_MOD_ID_TX_PPDU_STATS);
+
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
@@ -2662,7 +2696,7 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv(
 		ppdu_desc->vdev_id = peer->vdev->vdev_id;
 		qdf_mem_copy(ppdu_user_desc->mac_addr,
 			     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 	}
 	ppdu_user_desc->peer_id = peer_id;
 
@@ -2784,7 +2818,9 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
 	peer_id =
 	HTT_PPDU_STATS_USER_CMPLTN_BA_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
+				     DP_MOD_ID_TX_PPDU_STATS);
+
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
@@ -2792,7 +2828,7 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
 		ppdu_desc->vdev_id = peer->vdev->vdev_id;
 		qdf_mem_copy(ppdu_user_desc->mac_addr,
 			     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 	}
 	ppdu_user_desc->peer_id = peer_id;
 
@@ -2831,7 +2867,9 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
 	peer_id =
 	HTT_PPDU_STATS_USER_CMPLTN_BA_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
+				     DP_MOD_ID_TX_PPDU_STATS);
+
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
@@ -2839,7 +2877,7 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
 		ppdu_desc->vdev_id = peer->vdev->vdev_id;
 		qdf_mem_copy(ppdu_user_desc->mac_addr,
 			     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 	}
 	ppdu_user_desc->peer_id = peer_id;
 
@@ -2875,7 +2913,8 @@ static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(
 	peer_id =
 	HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_SW_PEER_ID_GET(*tag_buf);
 
-	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
+				     DP_MOD_ID_TX_PPDU_STATS);
 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
@@ -2883,7 +2922,7 @@ static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(
 		ppdu_desc->vdev_id = peer->vdev->vdev_id;
 		qdf_mem_copy(ppdu_user_desc->mac_addr,
 			     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 	}
 	if (!ppdu_user_desc->ack_ba_tlv) {
 		ppdu_user_desc->ack_ba_tlv = 1;
@@ -3018,7 +3057,8 @@ dp_process_ppdu_stats_user_compltn_flush_tlv(struct dp_pdev *pdev,
 	ppdu_desc->queue_type =
 			HTT_PPDU_STATS_FLUSH_TLV_QUEUE_TYPE_GET(*tag_buf);
 
-	peer = dp_peer_find_by_id(pdev->soc, peer_id);
+	peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
+				     DP_MOD_ID_TX_PPDU_STATS);
 	if (!peer)
 		goto add_ppdu_to_sched_list;
 
@@ -3028,7 +3068,7 @@ dp_process_ppdu_stats_user_compltn_flush_tlv(struct dp_pdev *pdev,
 			     ppdu_desc->num_msdu);
 	}
 
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 
 add_ppdu_to_sched_list:
 	ppdu_info->done = 1;
@@ -3084,8 +3124,9 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
 			uint32_t ppdu_id;
 
 			ppdu_id = ppdu_desc->ppdu_id;
-			peer = dp_peer_find_by_id(pdev->soc,
-						  ppdu_desc->user[i].peer_id);
+			peer = dp_peer_get_ref_by_id
+				(pdev->soc, ppdu_desc->user[i].peer_id,
+				 DP_MOD_ID_TX_PPDU_STATS);
 			/**
 			 * This check is to make sure peer is not deleted
 			 * after processing the TLVs.
@@ -3110,7 +3151,7 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
 			ppdu_desc->user[i].peer_last_delayed_ba =
 				peer->last_delayed_ba;
 
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 
 			if (ppdu_desc->user[i].delayed_ba &&
 			    !ppdu_desc->user[i].debug_copied) {
@@ -3137,8 +3178,10 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
 			uint64_t start_tsf;
 			uint64_t end_tsf;
 
-			peer = dp_peer_find_by_id(pdev->soc,
-						  ppdu_desc->user[i].peer_id);
+			peer = dp_peer_get_ref_by_id
+				(pdev->soc,
+				 ppdu_desc->user[i].peer_id,
+				 DP_MOD_ID_TX_PPDU_STATS);
 			/**
 			 * This check is to make sure peer is not deleted
 			 * after processing the TLVs.
@@ -3148,7 +3191,8 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
 
 			if (ppdu_desc->user[i].completion_status !=
 			    HTT_PPDU_STATS_USER_STATUS_OK) {
-				dp_peer_unref_delete(peer);
+				dp_peer_unref_delete(peer,
+						     DP_MOD_ID_TX_PPDU_STATS);
 				continue;
 			}
 
@@ -3166,7 +3210,7 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
 			}
 			ppdu_desc->user[i].peer_last_delayed_ba =
 				peer->last_delayed_ba;
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 		}
 	}
 
@@ -3506,7 +3550,8 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
 
 		peer = dp_peer_find_hash_find(pdev->soc,
 					      ppdu_desc->user[i].mac_addr,
-					      0, ppdu_desc->vdev_id);
+					      0, ppdu_desc->vdev_id,
+					      DP_MOD_ID_TX_PPDU_STATS);
 		/**
 		 * This check is to make sure peer is not deleted
 		 * after processing the TLVs.
@@ -3531,7 +3576,7 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
 		       (1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV)) &&
 		     (ppdu_desc->user[i].completion_status ==
 		      HTT_PPDU_STATS_USER_STATUS_OK))) {
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 			continue;
 		}
 
@@ -3557,7 +3602,7 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
 		dp_ppdu_desc_user_phy_tx_time_update(pdev, ppdu_desc,
 						     &ppdu_desc->user[i]);
 
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 		tlv_bitmap_expected = tlv_bitmap_default;
 	}
 }
@@ -4560,7 +4605,8 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
 			peer_id = HTT_RX_ADDBA_PEER_ID_GET(*msg_word);
 			tid = HTT_RX_ADDBA_TID_GET(*msg_word);
 			win_sz = HTT_RX_ADDBA_WIN_SIZE_GET(*msg_word);
-			peer = dp_peer_find_by_id(soc->dp_soc, peer_id);
+			peer = dp_peer_get_ref_by_id(soc->dp_soc, peer_id,
+						     DP_MOD_ID_HTT);
 
 			/*
 			 * Window size needs to be incremented by 1
@@ -4575,9 +4621,9 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
 
 				/*
 				 * If PEER_LOCK_REF_PROTECT enbled dec ref
-				 * which is inc by dp_peer_find_by_id
+				 * which is inc by dp_peer_get_ref_by_id
 				 */
-				dp_peer_unref_delete(peer);
+				dp_peer_unref_delete(peer, DP_MOD_ID_HTT);
 
 				QDF_TRACE(QDF_MODULE_ID_TXRX,
 					QDF_TRACE_LEVEL_INFO,
@@ -5251,6 +5297,7 @@ void
 dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type,
 			     uint32_t *tag_buf)
 {
+	struct dp_peer *peer = NULL;
 	switch (tag_type) {
 	case HTT_STATS_PEER_DETAILS_TAG:
 	{
@@ -5265,8 +5312,8 @@ dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type,
 		htt_peer_stats_cmn_tlv *dp_stats_buf =
 			(htt_peer_stats_cmn_tlv *)tag_buf;
 
-		struct dp_peer *peer = dp_peer_find_by_id(pdev->soc,
-						pdev->fw_stats_peer_id);
+		peer = dp_peer_get_ref_by_id(pdev->soc, pdev->fw_stats_peer_id,
+					     DP_MOD_ID_HTT);
 
 		if (peer && !peer->bss_peer) {
 			peer->stats.tx.inactive_time =
@@ -5274,7 +5321,7 @@ dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type,
 			qdf_event_set(&pdev->fw_peer_stats_event);
 		}
 		if (peer)
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_HTT);
 	}
 	break;
 	default:

+ 5 - 8
dp/wifi3.0/dp_internal.h

@@ -975,11 +975,12 @@ extern void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer);
 void dp_peer_tx_init(struct dp_pdev *pdev, struct dp_peer *peer);
 void dp_peer_cleanup(struct dp_vdev *vdev, struct dp_peer *peer);
 void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer);
-void dp_peer_unref_delete(struct dp_peer *peer);
-extern void *dp_find_peer_by_addr(struct cdp_pdev *dev,
-	uint8_t *peer_mac_addr);
+void dp_peer_unref_delete(struct dp_peer *peer, enum dp_peer_mod_id id);
 extern struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc,
-	uint8_t *peer_mac_addr, int mac_addr_is_aligned, uint8_t vdev_id);
+					      uint8_t *peer_mac_addr,
+					      int mac_addr_is_aligned,
+					      uint8_t vdev_id,
+					      enum dp_peer_mod_id id);
 
 #ifdef DP_PEER_EXTENDED_API
 /**
@@ -1046,10 +1047,6 @@ bool dp_find_peer_exist_on_other_vdev(struct cdp_soc_t *soc_hdl,
 				      uint8_t vdev_id, uint8_t *peer_addr,
 				      uint16_t max_bssid);
 
-void *dp_find_peer_by_addr_and_vdev(struct cdp_pdev *pdev_handle,
-		struct cdp_vdev *vdev,
-		uint8_t *peer_addr);
-
 /**
  * dp_peer_state_update() - update peer local state
  * @pdev - data path device instance

+ 10 - 10
dp/wifi3.0/dp_ipa.c

@@ -1764,7 +1764,7 @@ static qdf_nbuf_t dp_ipa_intrabss_send(struct dp_pdev *pdev,
 	struct dp_peer *vdev_peer;
 	uint16_t len;
 
-	vdev_peer = dp_vdev_bss_peer_ref_n_get(pdev->soc, vdev);
+	vdev_peer = dp_vdev_bss_peer_ref_n_get(pdev->soc, vdev, DP_MOD_ID_IPA);
 	if (qdf_unlikely(!vdev_peer))
 		return nbuf;
 
@@ -1773,12 +1773,12 @@ static qdf_nbuf_t dp_ipa_intrabss_send(struct dp_pdev *pdev,
 
 	if (dp_tx_send((struct cdp_soc_t *)pdev->soc, vdev->vdev_id, nbuf)) {
 		DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.fail, 1, len);
-		dp_peer_unref_delete(vdev_peer);
+		dp_peer_unref_delete(vdev_peer, DP_MOD_ID_IPA);
 		return nbuf;
 	}
 
 	DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.pkts, 1, len);
-	dp_peer_unref_delete(vdev_peer);
+	dp_peer_unref_delete(vdev_peer, DP_MOD_ID_IPA);
 	return NULL;
 }
 
@@ -1834,20 +1834,20 @@ bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	if (!qdf_mem_cmp(eh->h_dest, vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE))
 		return false;
 
-	da_peer = dp_find_peer_by_addr_and_vdev(dp_pdev_to_cdp_pdev(pdev),
-						dp_vdev_to_cdp_vdev(vdev),
-						eh->h_dest);
-
+	da_peer = dp_peer_find_hash_find(soc, eh->h_dest, 0, vdev->vdev_id,
+					 DP_MOD_ID_IPA);
 	if (!da_peer)
 		return false;
 
-	sa_peer = dp_find_peer_by_addr_and_vdev(dp_pdev_to_cdp_pdev(pdev),
-						dp_vdev_to_cdp_vdev(vdev),
-						eh->h_source);
+	dp_peer_unref_delete(da_peer, DP_MOD_ID_IPA);
 
+	da_peer = dp_peer_find_hash_find(soc, eh->h_source, 0, vdev->vdev_id,
+					 DP_MOD_ID_IPA);
 	if (!sa_peer)
 		return false;
 
+	dp_peer_unref_delete(sa_peer, DP_MOD_ID_IPA);
+
 	/*
 	 * In intra-bss forwarding scenario, skb is allocated by IPA driver.
 	 * Need to add skb to internal tracking table to avoid nbuf memory

+ 121 - 112
dp/wifi3.0/dp_main.c

@@ -635,12 +635,13 @@ static int dp_peer_add_ast_wifi3(struct cdp_soc_t *soc_hdl,
 	int ret = -1;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc_hdl,
-						       peer_mac, 0, vdev_id);
+						       peer_mac, 0, vdev_id,
+						       DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
-		goto fail;
+		return ret;
 	}
 
 	status = dp_peer_add_ast((struct dp_soc *)soc_hdl,
@@ -655,9 +656,8 @@ static int dp_peer_add_ast_wifi3(struct cdp_soc_t *soc_hdl,
 
 	dp_hmwds_ast_add_notify(peer, mac_addr,
 				type, status, false);
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return ret;
 }
@@ -672,12 +672,13 @@ static int dp_peer_update_ast_wifi3(struct cdp_soc_t *soc_hdl,
 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
 	struct dp_ast_entry  *ast_entry = NULL;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc_hdl,
-						       peer_mac, 0, vdev_id);
+						       peer_mac, 0, vdev_id,
+						       DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
-		goto fail;
+		return status;
 	}
 
 	qdf_spin_lock_bh(&soc->ast_lock);
@@ -691,9 +692,7 @@ static int dp_peer_update_ast_wifi3(struct cdp_soc_t *soc_hdl,
 	}
 	qdf_spin_unlock_bh(&soc->ast_lock);
 
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return status;
 }
@@ -725,16 +724,12 @@ static QDF_STATUS dp_wds_reset_ast_wifi3(struct cdp_soc_t *soc_hdl,
 
 	if (peer_mac_addr) {
 		peer = dp_peer_find_hash_find(soc, peer_mac_addr,
-					      0, vdev->vdev_id);
+					      0, vdev->vdev_id,
+					      DP_MOD_ID_CDP);
 		if (!peer) {
 			return QDF_STATUS_E_FAILURE;
 		}
 
-		if (peer->delete_in_progress) {
-			dp_peer_unref_delete(peer);
-			return QDF_STATUS_E_FAILURE;
-		}
-
 		qdf_spin_lock_bh(&soc->ast_lock);
 		DP_PEER_ITERATE_ASE_LIST(peer, ast_entry, tmp_ast_entry) {
 			if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM) ||
@@ -742,7 +737,7 @@ static QDF_STATUS dp_wds_reset_ast_wifi3(struct cdp_soc_t *soc_hdl,
 				dp_peer_del_ast(soc, ast_entry);
 		}
 		qdf_spin_unlock_bh(&soc->ast_lock);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 		return QDF_STATUS_SUCCESS;
 	} else if (wds_macaddr) {
@@ -5215,7 +5210,8 @@ static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc,
 
 	pdev = vdev->pdev;
 
-	vap_self_peer = dp_sta_vdev_self_peer_ref_n_get(soc, vdev);
+	vap_self_peer = dp_sta_vdev_self_peer_ref_n_get(soc, vdev,
+							DP_MOD_ID_PEER_CONFIG);
 	if (vap_self_peer) {
 		qdf_spin_lock_bh(&soc->ast_lock);
 		if (vap_self_peer->self_ast_entry) {
@@ -5226,7 +5222,7 @@ static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc,
 
 		dp_peer_delete_wifi3((struct cdp_soc_t *)soc, vdev->vdev_id,
 				     vap_self_peer->mac_addr.raw, 0);
-		dp_peer_unref_delete(vap_self_peer);
+		dp_peer_unref_delete(vap_self_peer, DP_MOD_ID_PEER_CONFIG);
 	}
 
 	/*
@@ -5309,14 +5305,15 @@ static inline struct dp_peer *dp_peer_can_reuse(struct dp_vdev *vdev,
 	struct dp_peer *peer;
 
 	peer = dp_peer_find_hash_find(vdev->pdev->soc, peer_mac_addr,
-				      0, vdev->vdev_id);
+				      0, vdev->vdev_id,
+				      DP_MOD_ID_PEER_CONFIG);
 	if (!peer)
 		return NULL;
 
 	if (peer->bss_peer)
 		return peer;
 
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_PEER_CONFIG);
 	return NULL;
 }
 #else
@@ -5326,14 +5323,15 @@ static inline struct dp_peer *dp_peer_can_reuse(struct dp_vdev *vdev,
 	struct dp_peer *peer;
 
 	peer = dp_peer_find_hash_find(vdev->pdev->soc, peer_mac_addr,
-				      0, vdev->vdev_id);
+				      0, vdev->vdev_id,
+				      DP_MOD_ID_PEER_CONFIG);
 	if (!peer)
 		return NULL;
 
 	if (peer->bss_peer && (peer->vdev->vdev_id == vdev->vdev_id))
 		return peer;
 
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_PEER_CONFIG);
 	return NULL;
 }
 #endif
@@ -5495,8 +5493,12 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 
 	qdf_atomic_init(&peer->ref_cnt);
 
+	for (i = 0; i < DP_MOD_ID_MAX; i++)
+		qdf_atomic_init(&peer->mod_refs[i]);
+
 	/* keep one reference for attach */
 	qdf_atomic_inc(&peer->ref_cnt);
+	qdf_atomic_inc(&peer->mod_refs[DP_MOD_ID_PEER_CONFIG]);
 
 	dp_peer_vdev_list_add(soc, vdev, peer);
 
@@ -5711,9 +5713,13 @@ dp_peer_setup_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	struct dp_vdev *vdev =
 			dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
 	struct dp_peer *peer =
-			dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id);
+			dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id,
+					       DP_MOD_ID_CDP);
 
-	if (!vdev || !peer || peer->delete_in_progress) {
+	if (!peer)
+		return QDF_STATUS_E_FAILURE;
+
+	if (!vdev) {
 		status = QDF_STATUS_E_FAILURE;
 		goto fail;
 	}
@@ -5754,8 +5760,7 @@ dp_peer_setup_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	dp_peer_ppdu_delayed_ba_init(peer);
 
 fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 	return status;
 }
 
@@ -6048,18 +6053,18 @@ static int dp_get_sec_type(struct cdp_soc_t *soc, uint8_t vdev_id,
 {
 	int sec_type = 0;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
-						       peer_mac, 0, vdev_id);
+						       peer_mac, 0, vdev_id,
+						       DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
-		goto fail;
+		return sec_type;
 	}
 
 	sec_type = peer->security[sec_idx].sec_type;
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 	return sec_type;
 }
 
@@ -6077,21 +6082,19 @@ dp_peer_authorize(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
-	struct dp_peer *peer = dp_peer_find_hash_find(soc,
-						      peer_mac,
-						      0, vdev_id);
+	struct dp_peer *peer = dp_peer_find_hash_find(soc, peer_mac,
+						      0, vdev_id,
+						      DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
 		status = QDF_STATUS_E_FAILURE;
 	} else {
 		peer->authorize = authorize ? 1 : 0;
+		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 	}
 
-	if (peer)
-		dp_peer_unref_delete(peer);
-
 	return status;
 }
 
@@ -6155,10 +6158,11 @@ free_vdev:
 
 /*
  * dp_peer_unref_delete() - unref and delete peer
- * @peer_handle:		Datapath peer handle
+ * @peer_handle:    Datapath peer handle
+ * @mod_id:         ID of module releasing reference
  *
  */
-void dp_peer_unref_delete(struct dp_peer *peer)
+void dp_peer_unref_delete(struct dp_peer *peer, enum dp_peer_mod_id mod_id)
 {
 	struct dp_vdev *vdev = peer->vdev;
 	struct dp_pdev *pdev = vdev->pdev;
@@ -6168,6 +6172,9 @@ void dp_peer_unref_delete(struct dp_peer *peer)
 	struct dp_peer *tmp_peer;
 	bool found = false;
 
+	if (mod_id > DP_MOD_ID_RX)
+		QDF_ASSERT(qdf_atomic_dec_return(&peer->mod_refs[mod_id]) >= 0);
+
 	/*
 	 * Hold the lock all the way from checking if the peer ref count
 	 * is zero until the peer references are removed from the hash
@@ -6265,7 +6272,8 @@ static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl,
 {
 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
 	struct dp_peer *peer = dp_peer_find_hash_find(soc, peer_mac,
-						      0, vdev_id);
+						      0, vdev_id,
+						      DP_MOD_ID_CDP);
 	struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
 
 	if (!vdev)
@@ -6279,7 +6287,7 @@ static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl,
 	}
 
 	if (!peer->valid) {
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 		dp_err("Invalid peer: %pM", peer_mac);
 		return QDF_STATUS_E_ALREADY;
 	}
@@ -6310,11 +6318,11 @@ static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl,
 	 * PEER_UNMAP message arrives to remove the other
 	 * reference, added by the PEER_MAP message.
 	 */
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_PEER_CONFIG);
 	/*
 	 * Remove the reference taken above
 	 */
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -6563,12 +6571,13 @@ static QDF_STATUS dp_get_peer_mac_from_peer_id(struct cdp_soc_t *soc,
 	struct dp_peer *peer;
 
 	if (soc && peer_mac) {
-		peer = dp_peer_find_by_id((struct dp_soc *)soc,
-					  (uint16_t)peer_id);
+		peer = dp_peer_get_ref_by_id((struct dp_soc *)soc,
+					     (uint16_t)peer_id,
+					     DP_MOD_ID_CDP);
 		if (peer) {
 			qdf_mem_copy(peer_mac, peer->mac_addr.raw,
 				     QDF_MAC_ADDR_SIZE);
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 			return QDF_STATUS_SUCCESS;
 		}
 	}
@@ -7253,33 +7262,30 @@ dp_txrx_host_stats_clr(struct dp_vdev *vdev, struct dp_soc *soc)
 static QDF_STATUS
 dp_get_host_peer_stats(struct cdp_soc_t *soc, uint8_t *mac_addr)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_peer *peer = NULL;
 
 	if (!mac_addr) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
 			  "%s: NULL peer mac addr\n", __func__);
-		status = QDF_STATUS_E_FAILURE;
-		goto fail;
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	peer = dp_peer_find_hash_find((struct dp_soc *)soc,
 				      mac_addr, 0,
-				      DP_VDEV_ALL);
-	if (!peer || peer->delete_in_progress) {
+				      DP_VDEV_ALL,
+				      DP_MOD_ID_CDP);
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
 			  "%s: Invalid peer\n", __func__);
-		status = QDF_STATUS_E_FAILURE;
-		goto fail;
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	dp_print_peer_stats(peer);
 	dp_peer_rxtid_stats(peer, dp_rx_tid_stats_cb, NULL);
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
 
-	return status;
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
+
+	return QDF_STATUS_SUCCESS;
 }
 
 /**
@@ -7860,10 +7866,11 @@ static QDF_STATUS dp_set_peer_param(struct cdp_soc_t *cdp_soc,  uint8_t vdev_id,
 				    cdp_config_param_type val)
 {
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc,
-						      peer_mac, 0, vdev_id);
+						      peer_mac, 0, vdev_id,
+						      DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress)
-		goto fail;
+	if (!peer)
+		return QDF_STATUS_E_FAILURE;
 
 	switch (param) {
 	case CDP_CONFIG_NAWDS:
@@ -7882,9 +7889,7 @@ static QDF_STATUS dp_set_peer_param(struct cdp_soc_t *cdp_soc,  uint8_t vdev_id,
 		break;
 	}
 
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -8050,13 +8055,17 @@ static void dp_rx_update_peer_delay_stats(struct dp_soc *soc,
 	if (peer_id > soc->max_peers)
 		return;
 
-	peer = dp_peer_find_by_id(soc, peer_id);
-	if (qdf_unlikely(!peer) || qdf_unlikely(!peer->pext_stats))
+	peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_CDP);
+	if (qdf_unlikely(!peer))
 		return;
 
-	pext_stats = peer->pext_stats;
-	ring_id = QDF_NBUF_CB_RX_CTX_ID(nbuf);
-	dp_rx_compute_tid_delay(&pext_stats->delay_stats[tid][ring_id], nbuf);
+	if (qdf_likely(peer->pext_stats)) {
+		pext_stats = peer->pext_stats;
+		ring_id = QDF_NBUF_CB_RX_CTX_ID(nbuf);
+		dp_rx_compute_tid_delay(&pext_stats->delay_stats[tid][ring_id],
+					nbuf);
+	}
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 }
 #else
 static inline void dp_rx_update_peer_delay_stats(struct dp_soc *soc,
@@ -8352,16 +8361,19 @@ dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc,
 				  uint8_t is_tx_pkt_cap_enable,
 				  uint8_t *peer_mac)
 {
-	QDF_STATUS status;
 	struct dp_peer *peer;
+	QDF_STATUS status;
 	struct dp_pdev *pdev =
-		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
-						   pdev_id);
+			dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
+							   pdev_id);
 	if (!pdev)
 		return QDF_STATUS_E_FAILURE;
 
-	peer = (struct dp_peer *)dp_find_peer_by_addr((struct cdp_pdev *)pdev,
-						      peer_mac);
+	peer = dp_peer_find_hash_find((struct dp_soc *)soc,
+				      peer_mac, 0, DP_VDEV_ALL,
+				      DP_MOD_ID_CDP);
+	if (!peer)
+		return QDF_STATUS_E_FAILURE;
 
 	/* we need to set tx pkt capture for non associated peer */
 	status = dp_peer_set_tx_capture_enabled(pdev, peer,
@@ -8371,6 +8383,7 @@ dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc,
 	status = dp_peer_set_rx_capture_enabled(pdev, peer,
 						is_rx_pkt_cap_enable,
 						peer_mac);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return status;
 }
@@ -8523,16 +8536,16 @@ dp_txrx_get_peer_stats(struct cdp_soc_t *soc, uint8_t vdev_id,
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
-						       peer_mac, 0, vdev_id);
+						       peer_mac, 0, vdev_id,
+						       DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
-		status = QDF_STATUS_E_FAILURE;
-	} else
-		qdf_mem_copy(peer_stats, &peer->stats,
-			     sizeof(struct cdp_peer_stats));
+	if (!peer)
+		return QDF_STATUS_E_FAILURE;
 
-	if (peer)
-		dp_peer_unref_delete(peer);
+	qdf_mem_copy(peer_stats, &peer->stats,
+		     sizeof(struct cdp_peer_stats));
+
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return status;
 }
@@ -8552,12 +8565,13 @@ dp_txrx_get_peer_stats_param(struct cdp_soc_t *soc, uint8_t vdev_id,
 {
 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
-						      peer_mac, 0, vdev_id);
+						      peer_mac, 0, vdev_id,
+						      DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 			  "Invalid Peer for Mac %pM", peer_mac);
-		ret = QDF_STATUS_E_FAILURE;
+		return QDF_STATUS_E_FAILURE;
 	} else if (type < cdp_peer_stats_max) {
 		switch (type) {
 		case cdp_peer_tx_ucast:
@@ -8614,8 +8628,7 @@ dp_txrx_get_peer_stats_param(struct cdp_soc_t *soc, uint8_t vdev_id,
 		ret = QDF_STATUS_E_FAILURE;
 	}
 
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return ret;
 }
@@ -8633,18 +8646,15 @@ dp_txrx_reset_peer_stats(struct cdp_soc_t *soc, uint8_t vdev_id,
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
-						       peer_mac, 0, vdev_id);
+						      peer_mac, 0, vdev_id,
+						      DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
-		status = QDF_STATUS_E_FAILURE;
-		goto fail;
-	}
+	if (!peer)
+		return QDF_STATUS_E_FAILURE;
 
 	qdf_mem_zero(&peer->stats, sizeof(peer->stats));
 
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return status;
 }
@@ -9385,7 +9395,8 @@ dp_peer_teardown_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_peer *peer =
-			dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id);
+			dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id,
+					       DP_MOD_ID_CDP);
 
 	/* Peer can be null for monitor vap mac address */
 	if (!peer) {
@@ -9399,8 +9410,7 @@ dp_peer_teardown_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	dp_peer_delete_ast_entries(soc, peer);
 	qdf_spin_unlock_bh(&soc->ast_lock);
 
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 	return status;
 }
 #endif
@@ -9506,13 +9516,11 @@ dp_enable_peer_based_pktlog(struct cdp_soc_t *soc, uint8_t pdev_id,
 		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
 						   pdev_id);
 
-	if (!pdev) {
-		dp_err("Invalid Pdev for pdev_id %d", pdev_id);
+	if (!pdev)
 		return QDF_STATUS_E_FAILURE;
-	}
 
-	peer = (struct dp_peer *)dp_find_peer_by_addr((struct cdp_pdev *)pdev,
-						      mac_addr);
+	peer = dp_peer_find_hash_find((struct dp_soc *)soc, mac_addr,
+				      0, DP_VDEV_ALL, DP_MOD_ID_CDP);
 
 	if (!peer) {
 		dp_err("Invalid Peer");
@@ -9522,6 +9530,8 @@ dp_enable_peer_based_pktlog(struct cdp_soc_t *soc, uint8_t pdev_id,
 	peer->peer_based_pktlog_filter = enb_dsb;
 	pdev->dp_peer_based_pktlog = enb_dsb;
 
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -9658,7 +9668,6 @@ static QDF_STATUS dp_flush_rate_stats_req(struct cdp_soc_t *soc_hdl,
 	struct dp_pdev *pdev =
 		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
 						   pdev_id);
-
 	if (!pdev)
 		return QDF_STATUS_E_FAILURE;
 
@@ -10475,7 +10484,7 @@ dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id)
 		return QDF_STATUS_E_INVAL;
 	}
 
-	peer = dp_vdev_bss_peer_ref_n_get(soc, vdev);
+	peer = dp_vdev_bss_peer_ref_n_get(soc, vdev, DP_MOD_ID_CDP);
 
 	if (!peer) {
 		dp_err("Peer is NULL");
@@ -10486,7 +10495,7 @@ dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id)
 
 	if (!rx_hw_stats) {
 		dp_err("malloc failed for hw stats structure");
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 		return QDF_STATUS_E_NOMEM;
 	}
 
@@ -10504,7 +10513,7 @@ dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id)
 		dp_err("no tid stats sent successfully");
 		qdf_mem_free(rx_hw_stats);
 		qdf_spin_unlock_bh(&soc->rx_hw_stats_lock);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 		return QDF_STATUS_E_INVAL;
 	}
 	qdf_atomic_set(&rx_hw_stats->pending_tid_stats_cnt,
@@ -10529,7 +10538,7 @@ dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id)
 		soc->ext_stats.rx_mpdu_missed = last_rx_mpdu_missed;
 	}
 	qdf_spin_unlock_bh(&soc->rx_hw_stats_lock);
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return status;
 }

+ 157 - 210
dp/wifi3.0/dp_peer.c

@@ -244,7 +244,8 @@ void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer)
 	index = dp_peer_find_hash_index(soc, &peer->mac_addr);
 	qdf_spin_lock_bh(&soc->peer_hash_lock);
 
-	if (dp_peer_get_ref(soc, peer) != QDF_STATUS_SUCCESS) {
+	if (dp_peer_get_ref(soc, peer, DP_MOD_ID_PEER_CONFIG) !=
+			QDF_STATUS_SUCCESS) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
 			  "unable to get peer reference at MAP mac %pM",
 			  peer ? peer->mac_addr.raw : NULL);
@@ -276,7 +277,8 @@ void dp_peer_vdev_list_add(struct dp_soc *soc, struct dp_vdev *vdev,
 			   struct dp_peer *peer)
 {
 	qdf_spin_lock_bh(&vdev->peer_list_lock);
-	if (dp_peer_get_ref(soc, peer) != QDF_STATUS_SUCCESS) {
+	if (dp_peer_get_ref(soc, peer, DP_MOD_ID_PEER_CONFIG) !=
+			QDF_STATUS_SUCCESS) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
 			  "unable to get peer reference at MAP mac %pM",
 			  peer ? peer->mac_addr.raw : NULL);
@@ -318,7 +320,7 @@ void dp_peer_vdev_list_remove(struct dp_soc *soc, struct dp_vdev *vdev,
 	if (found) {
 		TAILQ_REMOVE(&peer->vdev->peer_list, peer,
 			     peer_list_elem);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_PEER_CONFIG);
 	} else {
 		/*Ignoring the remove operation as peer not found*/
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
@@ -344,7 +346,8 @@ void dp_peer_find_id_to_obj_add(struct dp_soc *soc,
 
 	qdf_spin_lock_bh(&soc->peer_map_lock);
 
-	if (dp_peer_get_ref(soc, peer) != QDF_STATUS_SUCCESS) {
+	if (dp_peer_get_ref(soc, peer, DP_MOD_ID_PEER_CONFIG) !=
+			QDF_STATUS_SUCCESS) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
 			  "unable to get peer reference at MAP mac %pM peer_id %u",
 			  peer ? peer->mac_addr.raw : NULL, peer_id);
@@ -380,7 +383,7 @@ void dp_peer_find_id_to_obj_remove(struct dp_soc *soc,
 	qdf_spin_lock_bh(&soc->peer_map_lock);
 	peer = soc->peer_id_to_obj_map[peer_id];
 	soc->peer_id_to_obj_map[peer_id] = NULL;
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_PEER_CONFIG);
 	qdf_spin_unlock_bh(&soc->peer_map_lock);
 }
 
@@ -818,7 +821,7 @@ void dp_peer_free_hmwds_cb(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
 	}
 
 	peer = dp_peer_find_hash_find(soc, &param->peer_mac_addr.raw[0],
-				      0, param->vdev_id);
+				      0, param->vdev_id, DP_MOD_ID_AST);
 	if (peer) {
 		err = dp_peer_add_ast(soc, peer,
 				      &param->mac_addr.raw[0],
@@ -828,7 +831,7 @@ void dp_peer_free_hmwds_cb(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
 		dp_hmwds_ast_add_notify(peer, &param->mac_addr.raw[0],
 					param->type, err, false);
 
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_AST);
 	}
 	qdf_mem_free(cookie);
 }
@@ -1063,7 +1066,8 @@ add_ast_entry:
 		ast_entry->type = CDP_TXRX_AST_TYPE_MEC;
 		break;
 	case CDP_TXRX_AST_TYPE_DA:
-		vap_bss_peer = dp_vdev_bss_peer_ref_n_get(soc, vdev);
+		vap_bss_peer = dp_vdev_bss_peer_ref_n_get(soc, vdev,
+							  DP_MOD_ID_AST);
 		if (!vap_bss_peer) {
 			qdf_spin_unlock_bh(&soc->ast_lock);
 			qdf_mem_free(ast_entry);
@@ -1107,14 +1111,15 @@ add_ast_entry:
 				flags,
 				ast_entry->type)) {
 			if (vap_bss_peer)
-				dp_peer_unref_delete(vap_bss_peer);
+				dp_peer_unref_delete(vap_bss_peer,
+						     DP_MOD_ID_AST);
 			qdf_spin_unlock_bh(&soc->ast_lock);
 			return QDF_STATUS_SUCCESS;
 		}
 	}
 
 	if (vap_bss_peer)
-		dp_peer_unref_delete(vap_bss_peer);
+		dp_peer_unref_delete(vap_bss_peer, DP_MOD_ID_AST);
 
 	qdf_spin_unlock_bh(&soc->ast_lock);
 	return QDF_STATUS_E_FAILURE;
@@ -1602,12 +1607,14 @@ static int dp_peer_ast_free_entry_by_mac(struct dp_soc *soc,
  * @peer_mac_addr: peer mac address
  * @mac_addr_is_aligned: is mac addr alligned
  * @vdev_id: vdev_id
+ * @mod_id: id of module requesting reference
  *
  * return: peer in sucsess
  *         NULL in failure
  */
 struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc,
-	uint8_t *peer_mac_addr, int mac_addr_is_aligned, uint8_t vdev_id)
+	uint8_t *peer_mac_addr, int mac_addr_is_aligned, uint8_t vdev_id,
+	enum dp_peer_mod_id mod_id)
 {
 	union dp_align_mac_addr local_mac_addr_aligned, *mac_addr;
 	unsigned index;
@@ -1628,7 +1635,8 @@ struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc,
 			((peer->vdev->vdev_id == vdev_id) ||
 			 (vdev_id == DP_VDEV_ALL))) {
 			/* take peer reference before returning */
-			if (dp_peer_get_ref(soc, peer) != QDF_STATUS_SUCCESS)
+			if (dp_peer_get_ref(soc, peer, mod_id) !=
+						QDF_STATUS_SUCCESS)
 				peer = NULL;
 
 			qdf_spin_unlock_bh(&soc->peer_hash_lock);
@@ -1666,7 +1674,7 @@ void dp_peer_find_hash_remove(struct dp_soc *soc, struct dp_peer *peer)
 	QDF_ASSERT(found);
 	TAILQ_REMOVE(&soc->peer_hash.bins[index], peer, hash_list_elem);
 
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_PEER_CONFIG);
 	qdf_spin_unlock_bh(&soc->peer_hash_lock);
 }
 
@@ -1700,9 +1708,14 @@ void dp_peer_find_hash_erase(struct dp_soc *soc)
 				 */
 				/* set to zero */
 				qdf_atomic_init(&peer->ref_cnt);
+				for (i = 0; i < DP_MOD_ID_MAX; i++)
+					qdf_atomic_init(&peer->mod_refs[i]);
 				/* incr to one */
 				qdf_atomic_inc(&peer->ref_cnt);
-				dp_peer_unref_delete(peer);
+				qdf_atomic_inc(&peer->mod_refs
+						[DP_MOD_ID_PEER_CONFIG]);
+				dp_peer_unref_delete(peer,
+						     DP_MOD_ID_PEER_CONFIG);
 			}
 		}
 	}
@@ -1872,7 +1885,7 @@ static inline struct dp_peer *dp_peer_find_add_id(struct dp_soc *soc,
 	QDF_ASSERT(peer_id <= soc->max_peers);
 	/* check if there's already a peer object with this MAC address */
 	peer = dp_peer_find_hash_find(soc, peer_mac_addr,
-		0 /* is aligned */, vdev_id);
+		0 /* is aligned */, vdev_id, DP_MOD_ID_PEER_CONFIG);
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 		  "%s: peer %pK ID %d vid %d mac %pM",
 		  __func__, peer, peer_id, vdev_id, peer_mac_addr);
@@ -1933,12 +1946,13 @@ dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id,
 	 * obj map
 	 */
 	if (is_wds) {
-		peer = dp_peer_find_by_id(soc, peer_id);
+		peer = dp_peer_get_ref_by_id(soc, peer_id,
+					     DP_MOD_ID_HTT);
 
 		err = dp_peer_map_ast(soc, peer, peer_mac_addr, hw_peer_id,
 				      vdev_id, ast_hash, is_wds);
 		if (peer)
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_HTT);
 	} else {
 		/*
 		 * It's the responsibility of the CP and FW to ensure
@@ -2071,7 +2085,7 @@ dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id,
 	 * Remove a reference to the peer.
 	 * If there are no more references, delete the peer object.
 	 */
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_PEER_CONFIG);
 }
 
 void
@@ -2101,34 +2115,6 @@ static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt,
 	}
 }
 
-/*
- * dp_find_peer_by_addr - find peer instance by mac address
- * @dev: physical device instance
- * @peer_mac_addr: peer mac address
- *
- * Return: peer instance pointer
- */
-void *dp_find_peer_by_addr(struct cdp_pdev *dev, uint8_t *peer_mac_addr)
-{
-	struct dp_pdev *pdev = (struct dp_pdev *)dev;
-	struct dp_peer *peer;
-
-	peer = dp_peer_find_hash_find(pdev->soc, peer_mac_addr, 0, DP_VDEV_ALL);
-
-	if (!peer)
-		return NULL;
-
-	dp_verbose_debug("peer %pK mac: %pM", peer,
-			 peer->mac_addr.raw);
-
-	/* ref_cnt is incremented inside dp_peer_find_hash_find().
-	 * Decrement it here.
-	 */
-	dp_peer_unref_delete(peer);
-
-	return peer;
-}
-
 static bool dp_get_peer_vdev_roaming_in_progress(struct dp_peer *peer)
 {
 	struct ol_if_ops *ol_ops = NULL;
@@ -3010,10 +2996,11 @@ int dp_addba_resp_tx_completion_wifi3(struct cdp_soc_t *cdp_soc,
 				      uint8_t tid, int status)
 {
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc,
-						       peer_mac, 0, vdev_id);
+						       peer_mac, 0, vdev_id,
+						       DP_MOD_ID_CDP);
 	struct dp_rx_tid *rx_tid = NULL;
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
 		goto fail;
@@ -3082,12 +3069,12 @@ int dp_addba_resp_tx_completion_wifi3(struct cdp_soc_t *cdp_soc,
 	}
 
 success:
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 	return QDF_STATUS_SUCCESS;
 
 fail:
 	if (peer)
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return QDF_STATUS_E_FAILURE;
 }
@@ -3113,13 +3100,13 @@ dp_addba_responsesetup_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac,
 	struct dp_rx_tid *rx_tid = NULL;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc,
-						       peer_mac, 0, vdev_id);
+						       peer_mac, 0, vdev_id,
+						       DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
-		status = QDF_STATUS_E_FAILURE;
-		goto fail;
+		return QDF_STATUS_E_FAILURE;
 	}
 	rx_tid = &peer->rx_tid[tid];
 	qdf_spin_lock_bh(&rx_tid->tid_lock);
@@ -3131,9 +3118,7 @@ dp_addba_responsesetup_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac,
 	*batimeout  = 0;
 	qdf_spin_unlock_bh(&rx_tid->tid_lock);
 
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return status;
 }
@@ -3207,13 +3192,13 @@ int dp_addba_requestprocess_wifi3(struct cdp_soc_t *cdp_soc,
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_rx_tid *rx_tid = NULL;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc,
-						       peer_mac, 0, vdev_id);
+						       peer_mac, 0, vdev_id,
+						       DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
-		status = QDF_STATUS_E_FAILURE;
-		goto fail;
+		return QDF_STATUS_E_FAILURE;
 	}
 	rx_tid = &peer->rx_tid[tid];
 	qdf_spin_lock_bh(&rx_tid->tid_lock);
@@ -3277,8 +3262,7 @@ int dp_addba_requestprocess_wifi3(struct cdp_soc_t *cdp_soc,
 	qdf_spin_unlock_bh(&rx_tid->tid_lock);
 
 fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return status;
 }
@@ -3297,26 +3281,23 @@ dp_set_addba_response(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac,
 		      uint16_t vdev_id, uint8_t tid, uint16_t statuscode)
 {
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc,
-						       peer_mac, 0, vdev_id);
+						       peer_mac, 0, vdev_id,
+						       DP_MOD_ID_CDP);
 	struct dp_rx_tid *rx_tid;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
-		status = QDF_STATUS_E_FAILURE;
-		goto fail;
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	rx_tid = &peer->rx_tid[tid];
 	qdf_spin_lock_bh(&rx_tid->tid_lock);
 	rx_tid->userstatuscode = statuscode;
 	qdf_spin_unlock_bh(&rx_tid->tid_lock);
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
-	return status;
+	return QDF_STATUS_SUCCESS;
 }
 
 /*
@@ -3335,13 +3316,13 @@ int dp_delba_process_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac,
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_rx_tid *rx_tid;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc,
-						      peer_mac, 0, vdev_id);
+						      peer_mac, 0, vdev_id,
+						      DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
-		status = QDF_STATUS_E_FAILURE;
-		goto fail;
+		return QDF_STATUS_E_FAILURE;
 	}
 	rx_tid = &peer->rx_tid[tid];
 	qdf_spin_lock_bh(&rx_tid->tid_lock);
@@ -3363,8 +3344,7 @@ int dp_delba_process_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac,
 	peer->active_ba_session_cnt--;
 	qdf_spin_unlock_bh(&rx_tid->tid_lock);
 fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return status;
 }
@@ -3387,13 +3367,13 @@ int dp_delba_tx_completion_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac,
 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
 	struct dp_rx_tid *rx_tid = NULL;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc,
-						      peer_mac, 0, vdev_id);
+						      peer_mac, 0, vdev_id,
+						      DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!", __func__);
-		ret = QDF_STATUS_E_FAILURE;
-		goto end;
+		return QDF_STATUS_E_FAILURE;
 	}
 	rx_tid = &peer->rx_tid[tid];
 	qdf_spin_lock_bh(&rx_tid->tid_lock);
@@ -3432,8 +3412,7 @@ int dp_delba_tx_completion_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac,
 	qdf_spin_unlock_bh(&rx_tid->tid_lock);
 
 end:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return ret;
 }
@@ -3459,18 +3438,25 @@ dp_set_pn_check_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id,
 	int i;
 	uint8_t pn_size;
 	struct hal_reo_cmd_params params;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
-				peer_mac, 0, vdev_id);
+	struct dp_peer *peer = NULL;
 	struct dp_vdev *vdev =
 		dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
 						   vdev_id);
 
-	if (!vdev || !peer || peer->delete_in_progress) {
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: VDEV is NULL!\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	peer = dp_peer_find_hash_find((struct dp_soc *)soc,
+				      peer_mac, 0, vdev_id,
+				      DP_MOD_ID_CDP);
+
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
-		status = QDF_STATUS_E_FAILURE;
-		goto fail;
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	pdev = vdev->pdev;
@@ -3551,11 +3537,10 @@ dp_set_pn_check_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id,
 		}
 		qdf_spin_unlock_bh(&rx_tid->tid_lock);
 	}
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
 
-	return status;
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
+
+	return QDF_STATUS_SUCCESS;
 }
 
 
@@ -3577,15 +3562,14 @@ dp_set_key_sec_type_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id,
 			  bool is_unicast)
 {
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
-				peer_mac, 0, vdev_id);
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
+						       peer_mac, 0, vdev_id,
+						       DP_MOD_ID_CDP);
 	int sec_index;
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  "%s: Peer is NULL!\n", __func__);
-		status = QDF_STATUS_E_FAILURE;
-		goto fail;
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH,
@@ -3598,11 +3582,9 @@ dp_set_key_sec_type_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id,
 	sec_index = is_unicast ? dp_sec_ucast : dp_sec_mcast;
 	peer->security[sec_index].sec_type = sec_type;
 
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
-	return status;
+	return QDF_STATUS_SUCCESS;
 }
 
 void
@@ -3614,7 +3596,7 @@ dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id,
 	struct dp_peer *peer;
 	int sec_index;
 
-	peer = dp_peer_find_by_id(soc, peer_id);
+	peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_HTT);
 	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 			  "Couldn't find peer from ID %d - skipping security inits",
@@ -3668,7 +3650,7 @@ dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id,
 	 * is available
 	 */
 
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_HTT);
 }
 
 #ifdef QCA_PEER_EXT_STATS
@@ -3759,7 +3741,7 @@ dp_rx_delba_ind_handler(void *soc_handle, uint16_t peer_id,
 	struct dp_rx_tid *rx_tid;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
-	peer = dp_peer_find_by_id(soc, peer_id);
+	peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_HTT);
 
 	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
@@ -3804,7 +3786,7 @@ dp_rx_delba_ind_handler(void *soc_handle, uint16_t peer_id,
 		status = QDF_STATUS_E_FAILURE;
 	}
 
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_HTT);
 
 	return status;
 }
@@ -3815,13 +3797,9 @@ QDF_STATUS dp_register_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 {
 	struct dp_peer *peer;
 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
-	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
-
-	if (!pdev)
-		return QDF_STATUS_E_FAULT;
 
-	peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev,
-				    sta_desc->peer_addr.bytes);
+	peer = dp_peer_find_hash_find(soc, sta_desc->peer_addr.bytes,
+				      0, DP_VDEV_ALL, DP_MOD_ID_CDP);
 
 	if (!peer)
 		return QDF_STATUS_E_FAULT;
@@ -3832,6 +3810,8 @@ QDF_STATUS dp_register_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 
 	dp_rx_flush_rx_cached(peer, false);
 
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -3841,63 +3821,25 @@ dp_clear_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 {
 	struct dp_peer *peer;
 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
-	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
-
-	if (!pdev)
-		return QDF_STATUS_E_FAULT;
 
-	peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev, peer_addr.bytes);
+	peer = dp_peer_find_hash_find(soc, peer_addr.bytes,
+				      0, DP_VDEV_ALL, DP_MOD_ID_CDP);
 	if (!peer || !peer->valid)
 		return QDF_STATUS_E_FAULT;
 
 	dp_clear_peer_internal(soc, peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 	return QDF_STATUS_SUCCESS;
 }
 
-/**
- * dp_find_peer_by_addr_and_vdev() - Find peer by peer mac address within vdev
- * @pdev - data path device instance
- * @vdev - virtual interface instance
- * @peer_addr - peer mac address
- *
- * Find peer by peer mac address within vdev
- *
- * Return: peer instance void pointer
- *         NULL cannot find target peer
- */
-void *dp_find_peer_by_addr_and_vdev(struct cdp_pdev *pdev_handle,
-		struct cdp_vdev *vdev_handle,
-		uint8_t *peer_addr)
-{
-	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
-	struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle;
-	struct dp_peer *peer;
-
-	peer = dp_peer_find_hash_find(pdev->soc, peer_addr, 0, DP_VDEV_ALL);
-
-	if (!peer)
-		return NULL;
-
-	if (peer->vdev != vdev) {
-		dp_peer_unref_delete(peer);
-		return NULL;
-	}
-
-	/* ref_cnt is incremented inside dp_peer_find_hash_find().
-	 * Decrement it here.
-	 */
-	dp_peer_unref_delete(peer);
-
-	return peer;
-}
-
 QDF_STATUS dp_peer_state_update(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac,
 				enum ol_txrx_peer_state state)
 {
 	struct dp_peer *peer;
 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
 
-	peer =  dp_peer_find_hash_find(soc, peer_mac, 0, DP_VDEV_ALL);
+	peer =  dp_peer_find_hash_find(soc, peer_mac, 0, DP_VDEV_ALL,
+				       DP_MOD_ID_CDP);
 	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 			  "Failed to find peer for: [%pM]", peer_mac);
@@ -3909,7 +3851,7 @@ QDF_STATUS dp_peer_state_update(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac,
 	/* ref_cnt is incremented inside dp_peer_find_hash_find().
 	 * Decrement it here.
 	 */
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -3919,7 +3861,8 @@ QDF_STATUS dp_get_vdevid(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac,
 {
 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
 	struct dp_peer *peer =
-		dp_peer_find_hash_find(soc, peer_mac, 0, DP_VDEV_ALL);
+		dp_peer_find_hash_find(soc, peer_mac, 0, DP_VDEV_ALL,
+				       DP_MOD_ID_CDP);
 
 	if (!peer)
 		return QDF_STATUS_E_FAILURE;
@@ -3930,7 +3873,7 @@ QDF_STATUS dp_get_vdevid(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac,
 	/* ref_cnt is incremented inside dp_peer_find_hash_find().
 	 * Decrement it here.
 	 */
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -3941,6 +3884,7 @@ dp_get_vdev_by_peer_addr(struct cdp_pdev *pdev_handle,
 {
 	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
 	struct dp_peer *peer = NULL;
+	struct cdp_vdev *vdev = NULL;
 
 	if (!pdev) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH,
@@ -3949,7 +3893,8 @@ dp_get_vdev_by_peer_addr(struct cdp_pdev *pdev_handle,
 		return NULL;
 	}
 
-	peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev, peer_addr.bytes);
+	peer = dp_peer_find_hash_find(pdev->soc, peer_addr.bytes, 0,
+				      DP_VDEV_ALL, DP_MOD_ID_CDP);
 	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
 			  "PDEV not found for peer_addr: %pM",
@@ -3957,7 +3902,10 @@ dp_get_vdev_by_peer_addr(struct cdp_pdev *pdev_handle,
 		return NULL;
 	}
 
-	return (struct cdp_vdev *)peer->vdev;
+	vdev = (struct cdp_vdev *)peer->vdev;
+
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
+	return vdev;
 }
 
 /**
@@ -4003,14 +3951,14 @@ int dp_get_peer_state(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	enum ol_txrx_peer_state peer_state;
 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
 	struct dp_peer *peer =  dp_peer_find_hash_find(soc, peer_mac, 0,
-						       vdev_id);
+						       vdev_id, DP_MOD_ID_CDP);
 
 	if (!peer)
 		return QDF_STATUS_E_FAILURE;
 
 	DP_TRACE(DEBUG, "peer %pK stats %d", peer, peer->state);
 	peer_state = peer->state;
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return peer_state;
 }
@@ -4101,15 +4049,16 @@ bool dp_find_peer_exist_on_vdev(struct cdp_soc_t *soc_hdl,
 				uint8_t vdev_id, uint8_t *peer_addr)
 {
 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
-	struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
+	struct dp_peer *peer = NULL;
 
-	if (!vdev)
+	peer = dp_peer_find_hash_find(soc, peer_addr, 0, vdev_id,
+				      DP_MOD_ID_CDP);
+	if (!peer)
 		return false;
 
-	return !!dp_find_peer_by_addr_and_vdev(
-					dp_pdev_to_cdp_pdev(vdev->pdev),
-					dp_vdev_to_cdp_vdev(vdev),
-					peer_addr);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
+
+	return true;
 }
 
 bool dp_find_peer_exist_on_other_vdev(struct cdp_soc_t *soc_hdl,
@@ -4118,19 +4067,18 @@ bool dp_find_peer_exist_on_other_vdev(struct cdp_soc_t *soc_hdl,
 {
 	int i;
 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
-	struct dp_vdev *vdev;
+	struct dp_peer *peer = NULL;
 
 	for (i = 0; i < max_bssid; i++) {
-		vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, i);
 		/* Need to check vdevs other than the vdev_id */
-		if (vdev_id == i || !vdev)
+		if (vdev_id == i)
 			continue;
-		if (dp_find_peer_by_addr_and_vdev(
-					dp_pdev_to_cdp_pdev(vdev->pdev),
-					dp_vdev_to_cdp_vdev(vdev),
-					peer_addr)) {
+		peer = dp_peer_find_hash_find(soc, peer_addr, 0, i,
+					      DP_MOD_ID_CDP);
+		if (peer) {
 			dp_err("%s: Duplicate peer %pM already exist on vdev %d",
 			       __func__, peer_addr, i);
+			dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 			return true;
 		}
 	}
@@ -4142,12 +4090,16 @@ bool dp_find_peer_exist(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 			uint8_t *peer_addr)
 {
 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
-	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
+	struct dp_peer *peer = NULL;
 
-	if (!pdev)
-		return false;
+	peer = dp_peer_find_hash_find(soc, peer_addr, 0, DP_VDEV_ALL,
+				      DP_MOD_ID_CDP);
+	if (peer) {
+		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
+		return true;
+	}
 
-	return !!dp_find_peer_by_addr(dp_pdev_to_cdp_pdev(pdev), peer_addr);
+	return false;
 }
 #endif
 
@@ -4220,56 +4172,39 @@ dp_set_michael_key(struct cdp_soc_t *soc,
 		   uint8_t *peer_mac,
 		   bool is_unicast, uint32_t *key)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	uint8_t sec_index = is_unicast ? 1 : 0;
 	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
-						      peer_mac, 0, vdev_id);
+						      peer_mac, 0, vdev_id,
+						      DP_MOD_ID_CDP);
 
-	if (!peer || peer->delete_in_progress) {
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 			  "peer not found ");
-		status = QDF_STATUS_E_FAILURE;
-		goto fail;
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	qdf_mem_copy(&peer->security[sec_index].michael_key[0],
 		     key, IEEE80211_WEP_MICLEN);
 
-fail:
-	if (peer)
-		dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
-	return status;
+	return QDF_STATUS_SUCCESS;
 }
 
-bool dp_peer_find_by_id_valid(struct dp_soc *soc, uint16_t peer_id)
-{
-	struct dp_peer *peer = dp_peer_find_by_id(soc, peer_id);
-
-	if (peer) {
-		/*
-		 * Decrement the peer ref which is taken as part of
-		 * dp_peer_find_by_id if PEER_LOCK_REF_PROTECT is enabled
-		 */
-		dp_peer_unref_delete(peer);
-
-		return true;
-	}
-
-	return false;
-}
 
 /**
  * dp_vdev_bss_peer_ref_n_get: Get bss peer of a vdev
  * @soc: DP soc
  * @vdev: vdev
+ * @mod_id: id of module requesting reference
  *
  * Return: VDEV BSS peer
  */
 struct dp_peer *dp_vdev_bss_peer_ref_n_get(struct dp_soc *soc,
-					   struct dp_vdev *vdev)
+					   struct dp_vdev *vdev,
+					   enum dp_peer_mod_id mod_id)
 {
-	struct dp_peer *peer;
+	struct dp_peer *peer = NULL;
 
 	qdf_spin_lock_bh(&vdev->peer_list_lock);
 	TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
@@ -4277,11 +4212,16 @@ struct dp_peer *dp_vdev_bss_peer_ref_n_get(struct dp_soc *soc,
 			break;
 	}
 
-	if (!peer || !qdf_atomic_inc_not_zero(&peer->ref_cnt)) {
+	if (!peer) {
 		qdf_spin_unlock_bh(&vdev->peer_list_lock);
 		return NULL;
 	}
 
+	if (dp_peer_get_ref(soc, peer, mod_id) == QDF_STATUS_SUCCESS) {
+		qdf_spin_unlock_bh(&vdev->peer_list_lock);
+		return peer;
+	}
+
 	qdf_spin_unlock_bh(&vdev->peer_list_lock);
 	return peer;
 }
@@ -4290,11 +4230,13 @@ struct dp_peer *dp_vdev_bss_peer_ref_n_get(struct dp_soc *soc,
  * dp_sta_vdev_self_peer_ref_n_get: Get self peer of sta vdev
  * @soc: DP soc
  * @vdev: vdev
+ * @mod_id: id of module requesting reference
  *
  * Return: VDEV self peer
  */
 struct dp_peer *dp_sta_vdev_self_peer_ref_n_get(struct dp_soc *soc,
-						struct dp_vdev *vdev)
+						struct dp_vdev *vdev,
+						enum dp_peer_mod_id mod_id)
 {
 	struct dp_peer *peer;
 
@@ -4307,11 +4249,16 @@ struct dp_peer *dp_sta_vdev_self_peer_ref_n_get(struct dp_soc *soc,
 			break;
 	}
 
-	if (!peer || !qdf_atomic_inc_not_zero(&peer->ref_cnt)) {
+	if (!peer) {
 		qdf_spin_unlock_bh(&vdev->peer_list_lock);
 		return NULL;
 	}
 
+	if (dp_peer_get_ref(soc, peer, mod_id) == QDF_STATUS_SUCCESS) {
+		qdf_spin_unlock_bh(&vdev->peer_list_lock);
+		return peer;
+	}
+
 	qdf_spin_unlock_bh(&vdev->peer_list_lock);
 	return peer;
 }

+ 29 - 18
dp/wifi3.0/dp_peer.h

@@ -26,12 +26,27 @@
 
 #define DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC 5000
 
+/**
+ * dp_peer_get_ref() - Returns peer object given the peer id
+ *
+ * @soc		: core DP soc context
+ * @peer	: DP peer
+ * @mod_id	: id of module requesting the reference
+ *
+ * Return:	QDF_STATUS_SUCCESS if reference held successfully
+ *		else QDF_STATUS_E_INVAL
+ */
 static inline
-QDF_STATUS dp_peer_get_ref(struct dp_soc *soc, struct dp_peer *peer)
+QDF_STATUS dp_peer_get_ref(struct dp_soc *soc,
+			   struct dp_peer *peer,
+			   enum dp_peer_mod_id mod_id)
 {
 	if (!qdf_atomic_inc_not_zero(&peer->ref_cnt))
 		return QDF_STATUS_E_INVAL;
 
+	if (mod_id > DP_MOD_ID_RX)
+		qdf_atomic_inc(&peer->mod_refs[mod_id]);
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -45,7 +60,7 @@ QDF_STATUS dp_peer_get_ref(struct dp_soc *soc, struct dp_peer *peer)
  */
 static inline struct dp_peer *
 __dp_peer_find_by_id(struct dp_soc *soc,
-		   uint16_t peer_id)
+		     uint16_t peer_id)
 {
 	struct dp_peer *peer;
 
@@ -57,27 +72,30 @@ __dp_peer_find_by_id(struct dp_soc *soc,
 }
 
 /**
- * dp_peer_find_by_id() - Returns peer object given the peer id
+ * dp_peer_get_ref_by_id() - Returns peer object given the peer id
  *                        if delete_in_progress in not set for peer
  *
  * @soc		: core DP soc context
  * @peer_id	: peer id from peer object can be retrieved
+ * @mod_id      : ID ot module requesting reference
  *
  * Return: struct dp_peer*: Pointer to DP peer object
  */
 static inline
-struct dp_peer *dp_peer_find_by_id(struct dp_soc *soc,
-				   uint16_t peer_id)
+struct dp_peer *dp_peer_get_ref_by_id(struct dp_soc *soc,
+				      uint16_t peer_id,
+				      enum dp_peer_mod_id mod_id)
 {
 	struct dp_peer *peer;
 
 	qdf_spin_lock_bh(&soc->peer_map_lock);
 	peer = __dp_peer_find_by_id(soc, peer_id);
-	if (!peer || (peer && peer->delete_in_progress)) {
+	if (!peer || peer->delete_in_progress ||
+	    (dp_peer_get_ref(soc, peer, mod_id) != QDF_STATUS_SUCCESS)) {
 		qdf_spin_unlock_bh(&soc->peer_map_lock);
 		return NULL;
 	}
-	qdf_atomic_inc(&peer->ref_cnt);
+
 	qdf_spin_unlock_bh(&soc->peer_map_lock);
 
 	return peer;
@@ -177,15 +195,6 @@ void dp_peer_free_ast_entry(struct dp_soc *soc,
 void dp_peer_unlink_ast_entry(struct dp_soc *soc,
 			      struct dp_ast_entry *ast_entry);
 
-/*
- * dp_peer_find_by_id_exist - check if peer exists for given id
- * @soc: core DP soc context
- * @peer_id: peer id from peer object can be retrieved
- *
- * Return: true if peer exists of false otherwise
- */
-bool dp_peer_find_by_id_valid(struct dp_soc *soc, uint16_t peer_id);
-
 #define DP_AST_ASSERT(_condition) \
 	do { \
 		if (!(_condition)) { \
@@ -396,7 +405,9 @@ static inline void dp_peer_ext_stats_ctx_dealloc(struct dp_soc *soc,
 #endif
 
 struct dp_peer *dp_vdev_bss_peer_ref_n_get(struct dp_soc *soc,
-					   struct dp_vdev *vdev);
+					   struct dp_vdev *vdev,
+					   enum dp_peer_mod_id mod_id);
 struct dp_peer *dp_sta_vdev_self_peer_ref_n_get(struct dp_soc *soc,
-						struct dp_vdev *vdev);
+						struct dp_vdev *vdev,
+						enum dp_peer_mod_id mod_id);
 #endif /* _DP_PEER_H_ */

+ 6 - 4
dp/wifi3.0/dp_rx.c

@@ -2481,10 +2481,12 @@ done:
 		peer_id =  QDF_NBUF_CB_RX_PEER_ID(nbuf);
 
 		if (qdf_unlikely(!peer)) {
-			peer = dp_peer_find_by_id(soc, peer_id);
+			peer = dp_peer_get_ref_by_id(soc, peer_id,
+						     DP_MOD_ID_RX);
 		} else if (peer && peer->peer_id != peer_id) {
-			dp_peer_unref_delete(peer);
-			peer = dp_peer_find_by_id(soc, peer_id);
+			dp_peer_unref_delete(peer, DP_MOD_ID_RX);
+			peer = dp_peer_get_ref_by_id(soc, peer_id,
+						     DP_MOD_ID_RX);
 		}
 
 		if (peer) {
@@ -2754,7 +2756,7 @@ done:
 	}
 
 	if (qdf_likely(peer))
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_RX);
 
 	if (dp_rx_enable_eol_data_check(soc) && rx_bufs_used) {
 		if (quota) {

+ 7 - 6
dp/wifi3.0/dp_rx_defrag.c

@@ -212,7 +212,8 @@ void dp_rx_defrag_waitlist_flush(struct dp_soc *soc)
 				     rx_tid[rx_reorder->tid]);
 		qdf_spin_unlock_bh(&rx_reorder->tid_lock);
 
-		temp_peer = dp_peer_find_by_id(soc, peer->peer_id);
+		temp_peer = dp_peer_get_ref_by_id(soc, peer->peer_id,
+						  DP_MOD_ID_RX_ERR);
 		if (temp_peer == peer) {
 			qdf_spin_lock_bh(&rx_reorder->tid_lock);
 			dp_rx_reorder_flush_frag(peer, rx_reorder->tid);
@@ -220,7 +221,7 @@ void dp_rx_defrag_waitlist_flush(struct dp_soc *soc)
 		}
 
 		if (temp_peer)
-			dp_peer_unref_delete(temp_peer);
+			dp_peer_unref_delete(temp_peer, DP_MOD_ID_RX_ERR);
 
 	}
 }
@@ -1616,7 +1617,7 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc,
 	/* Check if the packet is from a valid peer */
 	peer_id = DP_PEER_METADATA_PEER_ID_GET(
 					mpdu_desc_info->peer_meta_data);
-	peer = dp_peer_find_by_id(soc, peer_id);
+	peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_RX_ERR);
 
 	if (!peer) {
 		/* We should not receive anything from unknown peer
@@ -1779,7 +1780,7 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc,
 			now_ms + pdev->soc->rx.defrag.timeout_ms;
 
 		dp_rx_defrag_waitlist_add(peer, tid);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 
 		return QDF_STATUS_SUCCESS;
 	}
@@ -1825,7 +1826,7 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc,
 
 	dp_rx_defrag_cleanup(peer, tid);
 
-	dp_peer_unref_delete(peer);
+	dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 
 	return QDF_STATUS_SUCCESS;
 
@@ -1842,7 +1843,7 @@ err_free_desc:
 
 end:
 	if (peer)
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 
 	DP_STATS_INC(soc, rx.rx_frag_err, 1);
 	return QDF_STATUS_E_DEFRAG_ERROR;

+ 14 - 14
dp/wifi3.0/dp_rx_err.c

@@ -395,7 +395,7 @@ dp_rx_pn_error_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc,
 				mpdu_desc_info->peer_meta_data);
 
 
-	peer = dp_peer_find_by_id(soc, peer_id);
+	peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_RX_ERR);
 
 	if (qdf_likely(peer)) {
 		/*
@@ -405,7 +405,7 @@ dp_rx_pn_error_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc,
 			"discard rx due to PN error for peer  %pK  %pM",
 			peer, peer->mac_addr.raw);
 
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 	}
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 		"Packet received with PN error");
@@ -442,7 +442,7 @@ dp_rx_oor_handle(struct dp_soc *soc,
 				FRAME_MASK_IPV4_EAPOL | FRAME_MASK_IPV6_DHCP;
 	struct dp_peer *peer = NULL;
 
-	peer = dp_peer_find_by_id(soc, peer_id);
+	peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_RX_ERR);
 	if (!peer) {
 		dp_info_rl("peer not found");
 		goto free_nbuf;
@@ -451,13 +451,13 @@ dp_rx_oor_handle(struct dp_soc *soc,
 	if (dp_rx_deliver_special_frame(soc, peer, nbuf, frame_mask,
 					rx_tlv_hdr)) {
 		DP_STATS_INC(soc, rx.err.reo_err_oor_to_stack, 1);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 		return;
 	}
 
 free_nbuf:
 	if (peer)
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 
 	DP_STATS_INC(soc, rx.err.reo_err_oor_drop, 1);
 	qdf_nbuf_free(nbuf);
@@ -789,7 +789,7 @@ dp_2k_jump_handle(struct dp_soc *soc,
 	struct dp_rx_tid *rx_tid = NULL;
 	uint32_t frame_mask = FRAME_MASK_IPV4_ARP;
 
-	peer = dp_peer_find_by_id(soc, peer_id);
+	peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_RX_ERR);
 	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 			  "peer not found");
@@ -833,14 +833,13 @@ nbuf_deliver:
 	if (dp_rx_deliver_special_frame(soc, peer, nbuf, frame_mask,
 					rx_tlv_hdr)) {
 		DP_STATS_INC(soc, rx.err.rx_2k_jump_to_stack, 1);
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 		return;
 	}
 
 free_nbuf:
 	if (peer)
-		dp_peer_unref_delete(peer);
-
+		dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 	DP_STATS_INC(soc, rx.err.rx_2k_jump_drop, 1);
 	qdf_nbuf_free(nbuf);
 }
@@ -883,8 +882,8 @@ dp_rx_null_q_handle_invalid_peer_id_exception(struct dp_soc *soc,
 	 * received MPDU
 	 */
 	if (wh)
-		peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev,
-					    wh->i_addr2);
+		peer = dp_peer_find_hash_find(soc, wh->i_addr2, 0,
+					      DP_VDEV_ALL, DP_MOD_ID_RX_ERR);
 	if (peer) {
 		dp_verbose_debug("MPDU sw_peer_id & ast_idx is corrupted");
 		hal_rx_dump_pkt_tlvs(soc->hal_soc, rx_tlv_hdr,
@@ -893,6 +892,7 @@ dp_rx_null_q_handle_invalid_peer_id_exception(struct dp_soc *soc,
 				 1, qdf_nbuf_len(nbuf));
 		qdf_nbuf_free(nbuf);
 
+		dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 		return true;
 	}
 	return false;
@@ -2014,7 +2014,7 @@ done:
 
 		peer_id = hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc,
 							   rx_tlv_hdr);
-		peer = dp_peer_find_by_id(soc, peer_id);
+		peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_RX_ERR);
 
 		if (!peer)
 			dp_info_rl("peer is null peer_id%u err_src%u err_rsn%u",
@@ -2041,7 +2041,7 @@ done:
 			dp_info_rl("scattered msdu dropped");
 			nbuf = next;
 			if (peer)
-				dp_peer_unref_delete(peer);
+				dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 			continue;
 		}
 
@@ -2176,7 +2176,7 @@ done:
 		}
 
 		if (peer)
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 
 		nbuf = next;
 	}

+ 3 - 2
dp/wifi3.0/dp_rx_mon_status.c

@@ -533,7 +533,8 @@ static void dp_rx_stats_update(struct dp_pdev *pdev,
 		ppdu_user = &ppdu->user[i];
 		if (ppdu_user->peer_id != HTT_INVALID_PEER)
 			peer = dp_peer_find_hash_find(soc, ppdu_user->mac_addr,
-						      0, ppdu_user->vdev_id);
+						      0, ppdu_user->vdev_id,
+						      DP_MOD_ID_RX_PPDU_STATS);
 
 		if (!peer)
 			peer = pdev->invalid_peer;
@@ -703,7 +704,7 @@ static void dp_rx_stats_update(struct dp_pdev *pdev,
 				     &peer->stats, ppdu->peer_id,
 				     UPDATE_PEER_STATS, pdev->pdev_id);
 #endif
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
 	}
 }
 #endif

+ 9 - 4
dp/wifi3.0/dp_stats.c

@@ -4307,7 +4307,8 @@ void dp_vdev_peer_stats_update_protocol_cnt(struct dp_vdev *vdev,
 		mac = eh->ether_dhost;
 
 	if (!peer) {
-		peer = dp_peer_find_hash_find(soc, mac, 0, vdev->vdev_id);
+		peer = dp_peer_find_hash_find(soc, mac, 0, vdev->vdev_id,
+					      DP_MOD_ID_GENERIC_STATS);
 		new_peer_ref = true;
 		if (!peer)
 			return;
@@ -4334,7 +4335,7 @@ void dp_vdev_peer_stats_update_protocol_cnt(struct dp_vdev *vdev,
 		protocol_trace_cnt[prot].ingress_cnt++;
 dp_vdev_peer_stats_update_protocol_cnt_free_peer:
 	if (new_peer_ref)
-		dp_peer_unref_delete(peer);
+		dp_peer_unref_delete(peer, DP_MOD_ID_GENERIC_STATS);
 }
 
 void dp_peer_stats_update_protocol_cnt(struct cdp_soc_t *soc,
@@ -6057,7 +6058,11 @@ dp_aggregate_pdev_ctrl_frames_stats(struct dp_pdev *pdev)
 				dp_err("DP Peer deletion in progress");
 				continue;
 			}
-			qdf_atomic_inc(&peer->ref_cnt);
+			if (dp_peer_get_ref(pdev->soc, peer,
+					    DP_MOD_ID_GENERIC_STATS) !=
+							QDF_STATUS_SUCCESS)
+				continue;
+
 			waitcnt = 0;
 			dp_peer_rxtid_stats(peer, dp_rx_bar_stats_cb, pdev);
 			while (!(qdf_atomic_read(&pdev->stats_cmd_complete)) &&
@@ -6067,7 +6072,7 @@ dp_aggregate_pdev_ctrl_frames_stats(struct dp_pdev *pdev)
 				waitcnt++;
 			}
 			qdf_atomic_set(&pdev->stats_cmd_complete, 0);
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_GENERIC_STATS);
 		}
 	}
 }

+ 9 - 7
dp/wifi3.0/dp_tx.c

@@ -3667,7 +3667,8 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
 		if (qdf_likely(desc->flags & DP_TX_DESC_FLAG_SIMPLE)) {
 			struct dp_pdev *pdev = desc->pdev;
 
-			peer = dp_peer_find_by_id(soc, desc->peer_id);
+			peer = dp_peer_get_ref_by_id(soc, desc->peer_id,
+						     DP_MOD_ID_TX_COMP);
 			if (qdf_likely(peer)) {
 				/*
 				 * Increment peer statistics
@@ -3680,7 +3681,7 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
 						HAL_TX_TQM_RR_FRAME_ACKED)
 					peer->stats.tx.tx_failed++;
 
-				dp_peer_unref_delete(peer);
+				dp_peer_unref_delete(peer, DP_MOD_ID_TX_COMP);
 			}
 
 			qdf_assert(pdev);
@@ -3701,7 +3702,8 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
 			continue;
 		}
 		hal_tx_comp_get_status(&desc->comp, &ts, soc->hal_soc);
-		peer = dp_peer_find_by_id(soc, ts.peer_id);
+		peer = dp_peer_get_ref_by_id(soc, ts.peer_id,
+					     DP_MOD_ID_TX_COMP);
 		dp_tx_comp_process_tx_status(soc, desc, &ts, peer, ring_id);
 
 		netbuf = desc->nbuf;
@@ -3712,14 +3714,13 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
 		dp_tx_comp_process_desc(soc, desc, &ts, peer);
 
 		if (peer)
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_TX_COMP);
 
 		next = desc->next;
 
 		dp_tx_desc_release(desc, desc->pool_id);
 		desc = next;
 	}
-
 }
 
 /**
@@ -3820,14 +3821,15 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status,
 			tid_stats->htt_status_cnt[tx_status]++;
 		}
 
-		peer = dp_peer_find_by_id(soc, ts.peer_id);
+		peer = dp_peer_get_ref_by_id(soc, ts.peer_id,
+					     DP_MOD_ID_TX_COMP);
 
 		dp_tx_comp_process_tx_status(soc, tx_desc, &ts, peer, ring_id);
 		dp_tx_comp_process_desc(soc, tx_desc, &ts, peer);
 		dp_tx_desc_release(tx_desc, tx_desc->pool_id);
 
 		if (qdf_likely(peer))
-			dp_peer_unref_delete(peer);
+			dp_peer_unref_delete(peer, DP_MOD_ID_TX_COMP);
 
 		break;
 	}

+ 23 - 0
dp/wifi3.0/dp_types.h

@@ -148,6 +148,27 @@ struct dp_rx_fst;
 struct dp_mon_filter;
 struct dp_mon_mpdu;
 
+/**
+ * enum for modules ids of peer reference
+ */
+enum dp_peer_mod_id {
+	DP_MOD_ID_TX_COMP,
+	DP_MOD_ID_RX,
+	DP_MOD_ID_RX_ERR,
+	DP_MOD_ID_TX_PPDU_STATS,
+	DP_MOD_ID_RX_PPDU_STATS,
+	DP_MOD_ID_CDP,
+	DP_MOD_ID_GENERIC_STATS,
+	DP_MOD_ID_TX_MULTIPASS,
+	DP_MOD_ID_TX_CAPTURE,
+	DP_MOD_ID_NSS_OFFLOAD,
+	DP_MOD_ID_PEER_CONFIG,
+	DP_MOD_ID_HTT,
+	DP_MOD_ID_IPA,
+	DP_MOD_ID_AST,
+	DP_MOD_ID_MAX,
+};
+
 #define DP_PDEV_ITERATE_VDEV_LIST(_pdev, _vdev) \
 	TAILQ_FOREACH((_vdev), &(_pdev)->vdev_list, vdev_list_elem)
 
@@ -2462,6 +2483,8 @@ struct dp_peer {
 #endif
 	/* entry to inactive_list*/
 	TAILQ_ENTRY(dp_peer) inactive_list_elem;
+
+	qdf_atomic_t mod_refs[DP_MOD_ID_MAX];
 };
 
 /*