diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index b412d7e9c0..31623af33b 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4771,6 +4771,33 @@ static void dp_vdev_register_wifi3(struct cdp_vdev *vdev_handle, "DP Vdev Register success"); } +/** + * dp_peer_flush_ast_entry() - Forcibily flush all AST entry of peer + * @soc: Datapath soc handle + * @peer: Datapath peer handle + * @peer_id: Peer ID + * @vdev_id: Vdev ID + * + * Return: void + */ +static inline void dp_peer_flush_ast_entry(struct dp_soc *soc, + struct dp_peer *peer, + uint16_t peer_id, + uint8_t vdev_id) +{ + struct dp_ast_entry *ase, *tmp_ase; + + if (soc->is_peer_map_unmap_v2) { + DP_PEER_ITERATE_ASE_LIST(peer, ase, tmp_ase) { + dp_rx_peer_unmap_handler + (soc, peer_id, + vdev_id, + ase->mac_addr.raw, + 1); + } + } +} + /** * dp_vdev_flush_peers() - Forcibily Flush peers of vdev * @vdev: Datapath VDEV handle @@ -4785,13 +4812,11 @@ static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool unmap_only) struct dp_soc *soc = pdev->soc; struct dp_peer *peer; uint16_t *peer_ids; - struct dp_ast_entry *ase, *tmp_ase; uint8_t i = 0, j = 0; peer_ids = qdf_mem_malloc(soc->max_peers * sizeof(peer_ids[0])); if (!peer_ids) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "DP alloc failure - unable to flush peers"); + dp_err("DP alloc failure - unable to flush peers"); return; } @@ -4805,70 +4830,33 @@ static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool unmap_only) qdf_spin_unlock_bh(&soc->peer_ref_mutex); for (i = 0; i < j ; i++) { - if (unmap_only) { - peer = __dp_peer_find_by_id(soc, peer_ids[i]); + peer = __dp_peer_find_by_id(soc, peer_ids[i]); - if (peer) { - if (soc->is_peer_map_unmap_v2) { - /* free AST entries of peer before - * release peer reference - */ - DP_PEER_ITERATE_ASE_LIST(peer, ase, - tmp_ase) { - dp_rx_peer_unmap_handler - (soc, peer_ids[i], - vdev->vdev_id, - ase->mac_addr.raw, - 1); - } - } - dp_rx_peer_unmap_handler(soc, peer_ids[i], - vdev->vdev_id, - peer->mac_addr.raw, - 0); - } - } else { - peer = __dp_peer_find_by_id(soc, peer_ids[i]); + if (!peer) + continue; - if (peer) { - dp_info("peer: %pM is getting flush", - peer->mac_addr.raw); + dp_info("peer: %pM is getting flush", + peer->mac_addr.raw); + /* free AST entries of peer */ + dp_peer_flush_ast_entry(soc, peer, + peer_ids[i], + vdev->vdev_id); + /* + * If peer flag valid is false, then dp_peer_delete_wifi3() + * is already executed, skip doing it again to avoid + * peer member invalid accessing. + */ + if (!unmap_only && peer->valid) + dp_peer_delete_wifi3(peer, 0); - if (soc->is_peer_map_unmap_v2) { - /* free AST entries of peer before - * release peer reference - */ - DP_PEER_ITERATE_ASE_LIST(peer, ase, - tmp_ase) { - dp_rx_peer_unmap_handler - (soc, peer_ids[i], - vdev->vdev_id, - ase->mac_addr.raw, - 1); - } - } - dp_peer_delete_wifi3(peer, 0); - /* - * we need to call dp_peer_unref_del_find_by_id - * to remove additional ref count incremented - * by dp_peer_find_by_id() call. - * - * Hold the ref count while executing - * dp_peer_delete_wifi3() call. - * - */ - dp_peer_unref_del_find_by_id(peer); - dp_rx_peer_unmap_handler(soc, peer_ids[i], - vdev->vdev_id, - peer->mac_addr.raw, 0); - } - } + dp_rx_peer_unmap_handler(soc, peer_ids[i], + vdev->vdev_id, + peer->mac_addr.raw, 0); } qdf_mem_free(peer_ids); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("Flushed peers for vdev object %pK "), vdev); + dp_info("Flushed peers for vdev object %pK ", vdev); } /*