diff --git a/dp/wifi3.0/dp_rx_defrag.c b/dp/wifi3.0/dp_rx_defrag.c index 4f0abd9669..28033a42ae 100644 --- a/dp/wifi3.0/dp_rx_defrag.c +++ b/dp/wifi3.0/dp_rx_defrag.c @@ -1702,7 +1702,7 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc, QDF_STATUS dp_rx_defrag_add_last_frag(struct dp_soc *soc, struct dp_peer *peer, uint16_t tid, - uint16_t rxseq, qdf_nbuf_t nbuf) + uint16_t rxseq, qdf_nbuf_t nbuf) { struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; struct dp_rx_reorder_array_elem *rx_reorder_array_elem; @@ -1712,6 +1712,22 @@ QDF_STATUS dp_rx_defrag_add_last_frag(struct dp_soc *soc, rx_reorder_array_elem = peer->rx_tid[tid].array; + /* + * HW may fill in unexpected peer_id in RX PKT TLV, + * if this peer_id related peer is valid by coincidence, + * but actually this peer won't do dp_peer_rx_init(like SAP vdev + * self peer), then invalid access to rx_reorder_array_elem happened. + */ + if (!rx_reorder_array_elem) { + dp_verbose_debug( + "peer id:%d mac:" QDF_MAC_ADDR_STR "drop rx frame!", + peer->peer_ids[0], + QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw)); + DP_STATS_INC(soc, rx.err.defrag_peer_uninit, 1); + qdf_nbuf_free(nbuf); + goto fail; + } + if (rx_reorder_array_elem->head && rxseq != rx_tid->curr_seq_num) { /* Drop stored fragments if out of sequence diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index b0d08c4d5c..1cdd2890a7 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -5096,6 +5096,8 @@ void dp_txrx_path_stats(struct dp_soc *soc) pdev->soc->stats.rx.err.rx_invalid_pkt_len.num); DP_PRINT_STATS("sa or da idx invalid %u", pdev->soc->stats.rx.err.invalid_sa_da_idx); + DP_PRINT_STATS("defrag peer uninit %u", + pdev->soc->stats.rx.err.defrag_peer_uninit); DP_PRINT_STATS("Reo Statistics"); DP_PRINT_STATS("rbm error: %u msdus", @@ -5556,6 +5558,8 @@ dp_print_soc_rx_stats(struct dp_soc *soc) soc->stats.rx.err.invalid_vdev); DP_PRINT_STATS("Invalid sa_idx or da_idx = %d", soc->stats.rx.err.invalid_sa_da_idx); + DP_PRINT_STATS("Defrag peer uninit = %d", + soc->stats.rx.err.defrag_peer_uninit); DP_PRINT_STATS("Invalid Pdev = %d", soc->stats.rx.err.invalid_pdev); DP_PRINT_STATS("Invalid Peer = %d", diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 7db7248429..3889be023d 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -690,6 +690,8 @@ struct dp_soc_stats { /* Invalid PDEV error count */ uint32_t invalid_pdev; + /* Defrag peer uninit error count */ + uint32_t defrag_peer_uninit; /* Invalid sa_idx or da_idx*/ uint32_t invalid_sa_da_idx; /* MSDU DONE failures */