From fdc6a808ae5f275db540bbce68af2b24e806ac06 Mon Sep 17 00:00:00 2001 From: Chaithanya Garrepalli Date: Fri, 14 Aug 2020 12:22:23 +0530 Subject: [PATCH] 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 --- dp/wifi3.0/dp_htt.c | 115 +++++++---- dp/wifi3.0/dp_internal.h | 13 +- dp/wifi3.0/dp_ipa.c | 20 +- dp/wifi3.0/dp_main.c | 233 ++++++++++----------- dp/wifi3.0/dp_peer.c | 367 +++++++++++++++------------------- dp/wifi3.0/dp_peer.h | 47 +++-- dp/wifi3.0/dp_rx.c | 10 +- dp/wifi3.0/dp_rx_defrag.c | 13 +- dp/wifi3.0/dp_rx_err.c | 28 +-- dp/wifi3.0/dp_rx_mon_status.c | 5 +- dp/wifi3.0/dp_stats.c | 13 +- dp/wifi3.0/dp_tx.c | 16 +- dp/wifi3.0/dp_types.h | 23 +++ 13 files changed, 474 insertions(+), 429 deletions(-) diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index a66754f754..7ae58e72df 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/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: diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index e630315c68..1eda52c423 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/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 diff --git a/dp/wifi3.0/dp_ipa.c b/dp/wifi3.0/dp_ipa.c index 0be7aeff7a..edd9cca523 100644 --- a/dp/wifi3.0/dp_ipa.c +++ b/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 diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 53bd8146bb..9905ae54d6 100644 --- a/dp/wifi3.0/dp_main.c +++ b/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; } diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index 55706da1c0..603cdbf451 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/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, ¶m->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, ¶m->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, ¶m->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; } diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index bef109e5e7..53a8b33247 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/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_ */ diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index a3de9d7621..d697a7f6b9 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/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) { diff --git a/dp/wifi3.0/dp_rx_defrag.c b/dp/wifi3.0/dp_rx_defrag.c index 7c0d6f3d18..5556f84196 100644 --- a/dp/wifi3.0/dp_rx_defrag.c +++ b/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; diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 3314e53a54..36fe4933d8 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/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; } diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 1a360bb714..06de15c62f 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/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 diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index 28266f1a68..b4a5c791bd 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/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); } } } diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 5036dbb813..e3fcb253d2 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/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; } diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 97061973b2..90e5172a4f 100644 --- a/dp/wifi3.0/dp_types.h +++ b/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]; }; /*