diff --git a/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c b/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c index 1abaf16438..3603b6cd91 100644 --- a/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c +++ b/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c @@ -1205,6 +1205,10 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev, } nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); + if (qdf_unlikely(!nbuf)) { + dp_mon_debug("nbuf is NULL"); + return num_buf_reaped; + } if (mpdu_info->decap_type == DP_MON_DECAP_FORMAT_INVALID) { /* decap type is invalid, drop the frame */ @@ -1305,6 +1309,10 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev, break; } nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); + if (qdf_unlikely(!nbuf)) { + dp_mon_debug("nbuf is NULL"); + break; + } num_frags = qdf_nbuf_get_nr_frags(nbuf); if (ppdu_info->mpdu_info[user_id].decap_type == HAL_HW_RX_DECAP_FORMAT_RAW) { @@ -1343,6 +1351,10 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev, break; } nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); + if (qdf_unlikely(!nbuf)) { + dp_mon_debug("nbuf is NULL"); + break; + } mpdu_meta = (struct hal_rx_mon_mpdu_info *)qdf_nbuf_data(nbuf); mpdu_info = &ppdu_info->mpdu_info[user_id]; mpdu_meta->decap_type = mpdu_info->decap_type; @@ -1361,6 +1373,10 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev, break; } nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); + if (qdf_unlikely(!nbuf)) { + dp_mon_debug("nbuf is NULL"); + break; + } mpdu_meta = (struct hal_rx_mon_mpdu_info *)qdf_nbuf_data(nbuf); mpdu_meta->mpdu_length_err = mpdu_info->mpdu_length_err; mpdu_meta->fcs_err = mpdu_info->fcs_err; diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index 6568547595..cbde7fd91a 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/qdf/linux/src/i_qdf_nbuf.h @@ -1805,12 +1805,21 @@ __qdf_nbuf_queue_insert_head(__qdf_nbuf_queue_t *qhead, __qdf_nbuf_t skb) qhead->qlen++; } +/** + * __qdf_nbuf_queue_remove_last() - remove a skb from the tail of the queue + * @qhead: Queue head + * + * This is a lockless version. Driver should take care of the locks + * + * Return: skb or NULL + */ static inline struct sk_buff * __qdf_nbuf_queue_remove_last(__qdf_nbuf_queue_t *qhead) { __qdf_nbuf_t tmp_tail, node = NULL; if (qhead->head) { + qhead->qlen--; tmp_tail = qhead->tail; node = qhead->head; if (qhead->head == qhead->tail) {