From d1f8fbb2259461f21a48afe75f8cd01d61ecdfb2 Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Sat, 11 Apr 2020 11:48:34 +0530 Subject: [PATCH] qcacmn: Clear the peer when it is deleted The peer rx packets should be flushed when deleting the peer and its state should be reset to DISCONNECT, when deleting the peer. If the state of peer is not set to DISCONNECT, then the flushing of rx packets for the peer which is being deleted will call the rx callback and submit these packet to the stack, which can cause unwanted behaviour. This way the UMAC does not need to specifically call clear peer before deleting the peer. Change-Id: I3b5a737126350a361d968f6349aef6291b2e3f56 CRs-Fixed: 2659629 --- dp/wifi3.0/dp_main.c | 17 +++++++++++------ dp/wifi3.0/dp_peer.c | 9 ++------- dp/wifi3.0/dp_peer.h | 25 +++++++++++++++++++++++++ dp/wifi3.0/dp_rx.h | 15 --------------- 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 5c7a16b02bcc..0cf622cc866a 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -171,7 +171,8 @@ static void dp_pktlogmod_exit(struct dp_pdev *handle); static inline QDF_STATUS dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, uint8_t *peer_mac_addr); -static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id, +static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, uint8_t *peer_mac, uint32_t bitmap); static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool unmap_only); @@ -6721,7 +6722,6 @@ void dp_peer_unref_delete(struct dp_peer *peer) #ifdef PEER_CACHE_RX_PKTS static inline void dp_peer_rx_bufq_resources_deinit(struct dp_peer *peer) { - dp_rx_flush_rx_cached(peer, true); qdf_list_destroy(&peer->bufq_info.cached_bufq); qdf_spinlock_destroy(&peer->bufq_info.bufq_lock); } @@ -6733,17 +6733,19 @@ static inline void dp_peer_rx_bufq_resources_deinit(struct dp_peer *peer) /* * dp_peer_detach_wifi3() – Detach txrx peer - * @soc: soc handle + * @soc_hdl: soc handle * @vdev_id: id of dp handle * @peer_mac: mac of datapath PEER handle * @bitmap: bitmap indicating special handling of request. * */ -static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id, +static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, uint8_t *peer_mac, uint32_t bitmap) { - struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, - peer_mac, 0, vdev_id); + 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); /* Peer can be null for monitor vap mac address */ if (!peer) { @@ -6765,6 +6767,9 @@ static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id, dp_local_peer_id_free(peer->vdev->pdev, peer); + /* Drop all rx packets before deleting peer */ + dp_clear_peer_internal(soc, peer); + dp_peer_rx_bufq_resources_deinit(peer); qdf_spinlock_destroy(&peer->peer_info_lock); diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index 3a448fe090e4..6a23a101dcd4 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -3400,15 +3400,10 @@ dp_clear_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, return QDF_STATUS_E_FAULT; peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev, peer_addr.bytes); - if (!peer) + if (!peer || !peer->valid) return QDF_STATUS_E_FAULT; - qdf_spin_lock_bh(&peer->peer_info_lock); - peer->state = OL_TXRX_PEER_STATE_DISC; - qdf_spin_unlock_bh(&peer->peer_info_lock); - - dp_rx_flush_rx_cached(peer, true); - + dp_clear_peer_internal(soc, peer); return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index be62b4fa772d..5f0a9c8e9fe1 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/dp/wifi3.0/dp_peer.h @@ -89,6 +89,31 @@ dp_peer_find_by_id(struct dp_soc *soc, } #endif /* PEER_LOCK_REF_PROTECT */ +#ifdef PEER_CACHE_RX_PKTS +/** + * dp_rx_flush_rx_cached() - flush cached rx frames + * @peer: peer + * @drop: set flag to drop frames + * + * Return: None + */ +void dp_rx_flush_rx_cached(struct dp_peer *peer, bool drop); +#else +static inline void dp_rx_flush_rx_cached(struct dp_peer *peer, bool drop) +{ +} +#endif + +static inline void +dp_clear_peer_internal(struct dp_soc *soc, struct dp_peer *peer) +{ + qdf_spin_lock_bh(&peer->peer_info_lock); + peer->state = OL_TXRX_PEER_STATE_DISC; + qdf_spin_unlock_bh(&peer->peer_info_lock); + + dp_rx_flush_rx_cached(peer, true); +} + void dp_print_ast_stats(struct dp_soc *soc); void dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, uint16_t hw_peer_id, uint8_t vdev_id, diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index c07d841f6628..9f048becbc66 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -1139,21 +1139,6 @@ void dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, struct dp_peer *peer, uint8_t err_code, uint8_t mac_id); -#ifdef PEER_CACHE_RX_PKTS -/** - * dp_rx_flush_rx_cached() - flush cached rx frames - * @peer: peer - * @drop: set flag to drop frames - * - * Return: None - */ -void dp_rx_flush_rx_cached(struct dp_peer *peer, bool drop); -#else -static inline void dp_rx_flush_rx_cached(struct dp_peer *peer, bool drop) -{ -} -#endif - #ifndef QCA_MULTIPASS_SUPPORT static inline bool dp_rx_multipass_process(struct dp_peer *peer, qdf_nbuf_t nbuf, uint8_t tid)