diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c index f717d39594ec..7a51a9f57d06 100644 --- a/core/dp/htt/htt_rx.c +++ b/core/dp/htt/htt_rx.c @@ -1472,6 +1472,13 @@ htt_rx_frag_pop_hl( return 0; } +static inline int +htt_rx_offload_msdu_cnt_hl( + htt_pdev_handle pdev) +{ + return 1; +} + static inline int htt_rx_offload_msdu_pop_hl(htt_pdev_handle pdev, qdf_nbuf_t offload_deliver_msg, @@ -1518,6 +1525,13 @@ htt_rx_offload_msdu_pop_hl(htt_pdev_handle pdev, } #endif +static inline int +htt_rx_offload_msdu_cnt_ll( + htt_pdev_handle pdev) +{ + return htt_rx_ring_elems(pdev); +} + static int htt_rx_offload_msdu_pop_ll(htt_pdev_handle pdev, qdf_nbuf_t offload_deliver_msg, @@ -2856,6 +2870,10 @@ int (*htt_rx_frag_pop)(htt_pdev_handle pdev, qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu, uint32_t *msdu_count); +int +(*htt_rx_offload_msdu_cnt)( + htt_pdev_handle pdev); + int (*htt_rx_offload_msdu_pop)(htt_pdev_handle pdev, qdf_nbuf_t offload_deliver_msg, @@ -3525,6 +3543,7 @@ int htt_rx_attach(struct htt_pdev_t *pdev) pdev->rx_ring.base_paddr = 0; htt_rx_amsdu_pop = htt_rx_amsdu_pop_hl; htt_rx_frag_pop = htt_rx_frag_pop_hl; + htt_rx_offload_msdu_cnt = htt_rx_offload_msdu_cnt_hl; htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_hl; htt_rx_mpdu_desc_list_next = htt_rx_mpdu_desc_list_next_hl; htt_rx_mpdu_desc_retry = htt_rx_mpdu_desc_retry_hl; @@ -3670,6 +3689,7 @@ int htt_rx_attach(struct htt_pdev_t *pdev) if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) htt_rx_amsdu_pop = htt_rx_mon_amsdu_rx_in_order_pop_ll; + htt_rx_offload_msdu_cnt = htt_rx_offload_msdu_cnt_ll; htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_ll; htt_rx_mpdu_desc_retry = htt_rx_mpdu_desc_retry_ll; htt_rx_mpdu_desc_seq_num = htt_rx_mpdu_desc_seq_num_ll; diff --git a/core/dp/htt/htt_t2h.c b/core/dp/htt/htt_t2h.c index 335541f92651..0c072099d6cf 100644 --- a/core/dp/htt/htt_t2h.c +++ b/core/dp/htt/htt_t2h.c @@ -254,7 +254,7 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg, } case HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND: { - int msdu_cnt; + uint16_t msdu_cnt; msdu_cnt = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_GET(*msg_word); diff --git a/core/dp/ol/inc/ol_htt_rx_api.h b/core/dp/ol/inc/ol_htt_rx_api.h index 90278ea4fb1c..54e7ab9dde63 100644 --- a/core/dp/ol/inc/ol_htt_rx_api.h +++ b/core/dp/ol/inc/ol_htt_rx_api.h @@ -664,6 +664,15 @@ extern int qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu, uint32_t *msdu_count); +/** + * @brief Return the maximum number of available msdus currently + * + * @param pdev - the HTT instance the rx data was received on + */ +extern int +(*htt_rx_offload_msdu_cnt)( + htt_pdev_handle pdev); + /** * @brief Return a linked list of buffers holding one MSDU * In some systems the buffers are delivered along with offload delivery diff --git a/core/dp/ol/inc/ol_txrx_htt_api.h b/core/dp/ol/inc/ol_txrx_htt_api.h index 53abfa5afceb..31ec8a5151cd 100644 --- a/core/dp/ol/inc/ol_txrx_htt_api.h +++ b/core/dp/ol/inc/ol_txrx_htt_api.h @@ -420,7 +420,7 @@ void ol_rx_frag_indication_handler(ol_txrx_pdev_handle pdev, */ void ol_rx_offload_deliver_ind_handler(ol_txrx_pdev_handle pdev, - qdf_nbuf_t msg, int msdu_cnt); + qdf_nbuf_t msg, uint16_t msdu_cnt); /** * @brief Process a peer map message sent by the target. diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c index f2e28415bd63..65aa6c48fc36 100644 --- a/core/dp/txrx/ol_rx.c +++ b/core/dp/txrx/ol_rx.c @@ -920,7 +920,7 @@ ol_rx_inspect(struct ol_txrx_vdev_t *vdev, void ol_rx_offload_deliver_ind_handler(ol_txrx_pdev_handle pdev, - qdf_nbuf_t msg, int msdu_cnt) + qdf_nbuf_t msg, uint16_t msdu_cnt) { int vdev_id, peer_id, tid; qdf_nbuf_t head_buf, tail_buf, buf; @@ -928,6 +928,17 @@ ol_rx_offload_deliver_ind_handler(ol_txrx_pdev_handle pdev, uint8_t fw_desc; htt_pdev_handle htt_pdev = pdev->htt_pdev; + if (msdu_cnt > htt_rx_offload_msdu_cnt(htt_pdev)) { + ol_txrx_err("%s: invalid msdu_cnt=%u\n", + __func__, + msdu_cnt); + + if (pdev->cfg.is_high_latency) + htt_rx_desc_frame_free(htt_pdev, msg); + + return; + } + while (msdu_cnt) { if (!htt_rx_offload_msdu_pop(htt_pdev, msg, &vdev_id, &peer_id, &tid, &fw_desc, &head_buf, &tail_buf)) {