From c1aeb35c3c938f3d8be824656f155481a5d0d7c4 Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Tue, 14 Jan 2020 13:06:15 +0530 Subject: [PATCH] qcacmn: Do not process RX packet if vdev is pending delete If the vdev is marked as delete in progress, then the packets received on that particular vdev should not be submitted to the network stack. Drop the packets if the vdev is marked to be deleted. CRs-Fixed: 2599128 Change-Id: I0996669bea368b6c0afc10e1d929bc2f314ae6fe --- dp/wifi3.0/dp_rx.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 6b351a24e33a..b3cebd2dc4f4 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -1159,9 +1159,11 @@ static inline int dp_rx_drop_nbuf_list(struct dp_pdev *pdev, ring_id = QDF_NBUF_CB_RX_CTX_ID(buf); next_buf = qdf_nbuf_queue_next(buf); tid = qdf_nbuf_get_tid_val(buf); - stats = &pdev->stats.tid_stats.tid_rx_stats[ring_id][tid]; - stats->fail_cnt[INVALID_PEER_VDEV]++; - stats->delivered_to_stack--; + if (qdf_likely(pdev)) { + stats = &pdev->stats.tid_stats.tid_rx_stats[ring_id][tid]; + stats->fail_cnt[INVALID_PEER_VDEV]++; + stats->delivered_to_stack--; + } qdf_nbuf_free(buf); buf = next_buf; num_dropped++; @@ -1302,11 +1304,25 @@ dp_rx_enqueue_rx(struct dp_peer *peer, qdf_nbuf_t rx_buf_list) } #endif -static inline void dp_rx_deliver_to_stack(struct dp_vdev *vdev, - struct dp_peer *peer, - qdf_nbuf_t nbuf_head, - qdf_nbuf_t nbuf_tail) +static inline void dp_rx_deliver_to_stack(struct dp_soc *soc, + struct dp_vdev *vdev, + struct dp_peer *peer, + qdf_nbuf_t nbuf_head, + qdf_nbuf_t nbuf_tail) { + int num_nbuf = 0; + + if (qdf_unlikely(!vdev || vdev->delete.pending)) { + num_nbuf = dp_rx_drop_nbuf_list(NULL, nbuf_head); + /* + * This is a special case where vdev is invalid, + * so we cannot know the pdev to which this packet + * belonged. Hence we update the soc rx error stats. + */ + DP_STATS_INC(soc, rx.err.invalid_vdev, num_nbuf); + return; + } + /* * highly unlikely to have a vdev without a registered rx * callback function. if so let us free the nbuf_list. @@ -1614,7 +1630,7 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf) vdev_id = QDF_NBUF_CB_RX_VDEV_ID(nbuf); vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); - if (!vdev || !vdev->osif_rx) + if (!vdev || vdev->delete.pending || !vdev->osif_rx) goto deliver_fail; rx_tlv_hdr = qdf_nbuf_data(nbuf); @@ -1994,7 +2010,8 @@ done: vdev_id = QDF_NBUF_CB_RX_VDEV_ID(nbuf); if (deliver_list_head && vdev && (vdev->vdev_id != vdev_id)) { - dp_rx_deliver_to_stack(vdev, peer, deliver_list_head, + dp_rx_deliver_to_stack(soc, vdev, peer, + deliver_list_head, deliver_list_tail); deliver_list_head = NULL; deliver_list_tail = NULL; @@ -2251,7 +2268,8 @@ done: if (qdf_likely(deliver_list_head)) { if (qdf_likely(peer)) - dp_rx_deliver_to_stack(vdev, peer, deliver_list_head, + dp_rx_deliver_to_stack(soc, vdev, peer, + deliver_list_head, deliver_list_tail); else { nbuf = deliver_list_head;