From 753eed32c155e24a86a025c7a92569601a585f97 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Tue, 22 Jan 2019 15:40:15 +0530 Subject: [PATCH] qcacmn: free the dp peers before cp peers in fw recovey case Free the pending dp peers before cp peers in fw recovey case, to make sure dp peers release all cp peer references they hold. Change-Id: Ie6c7562e7214f40be895cf8a57a1aa6245d717cb CRs-fixed: 2383984 --- dp/inc/cdp_txrx_cmn.h | 18 ++++++++++++++++++ dp/inc/cdp_txrx_ops.h | 2 ++ dp/wifi3.0/dp_main.c | 14 +++++++++----- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index af49b04f0b1e..dc20849f87a4 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -589,6 +589,24 @@ static inline void cdp_peer_teardown soc->ops->cmn_drv_ops->txrx_peer_teardown(vdev, peer); } +static inline void +cdp_vdev_flush_peers(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, + bool unmap_only) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->txrx_vdev_flush_peers) + return; + + soc->ops->cmn_drv_ops->txrx_vdev_flush_peers(vdev, unmap_only); +} + static inline void cdp_peer_delete(ol_txrx_soc_handle soc, void *peer, uint32_t bitmap) { diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 71f1dfe1069b..df01880c22b0 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -133,6 +133,8 @@ struct cdp_cmn_ops { void (*txrx_peer_delete)(void *peer, uint32_t bitmap); + void (*txrx_vdev_flush_peers)(struct cdp_vdev *vdev, bool unmap_only); + QDF_STATUS (*txrx_set_monitor_mode)(struct cdp_vdev *vdev, uint8_t smart_monitor); void (*txrx_peer_delete_sync)(void *peer, diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 9f4c74765cb4..fc138a393104 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4374,11 +4374,13 @@ static void dp_vdev_register_wifi3(struct cdp_vdev *vdev_handle, /** * dp_vdev_flush_peers() - Forcibily Flush peers of vdev * @vdev: Datapath VDEV handle + * @unmap_only: Flag to indicate "only unmap" * * Return: void */ -static void dp_vdev_flush_peers(struct dp_vdev *vdev) +static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool unmap_only) { + struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_pdev *pdev = vdev->pdev; struct dp_soc *soc = pdev->soc; struct dp_peer *peer; @@ -4406,7 +4408,9 @@ static void dp_vdev_flush_peers(struct dp_vdev *vdev) if (peer) { dp_info("peer: %pM is getting flush", peer->mac_addr.raw); - dp_peer_delete_wifi3(peer, 0); + + if (!unmap_only) + dp_peer_delete_wifi3(peer, 0); /* * we need to call dp_peer_unref_del_find_by_id() * to remove additional ref count incremented @@ -4459,9 +4463,8 @@ static void dp_vdev_detach_wifi3(struct cdp_vdev *vdev_handle, * this will free all references held due to missing * unmap commands from Target */ - if ((hif_get_target_status(soc->hif_handle) == TARGET_STATUS_RESET) || - !hif_is_target_ready(HIF_GET_SOFTC(soc->hif_handle))) - dp_vdev_flush_peers(vdev); + if (!hif_is_target_ready(HIF_GET_SOFTC(soc->hif_handle))) + dp_vdev_flush_peers((struct cdp_vdev *)vdev, false); /* * Use peer_ref_mutex while accessing peer_list, in case @@ -9037,6 +9040,7 @@ static struct cdp_cmn_ops dp_ops_cmn = { dp_peer_ast_entry_del_by_pdev, .txrx_peer_delete = dp_peer_delete_wifi3, .txrx_vdev_register = dp_vdev_register_wifi3, + .txrx_vdev_flush_peers = dp_vdev_flush_peers, .txrx_soc_detach = dp_soc_detach_wifi3, .txrx_soc_deinit = dp_soc_deinit_wifi3, .txrx_soc_init = dp_soc_init_wifi3,