diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index 7c8f185963..3688f7c111 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -2223,6 +2223,26 @@ cdp_peer_map_attach(ol_txrx_soc_handle soc, uint32_t max_peers, return QDF_STATUS_SUCCESS; } +/* cdp_soc_set_param() - CDP API to set soc parameters + * @soc: opaque soc handle + * @param: parameter type + * @value: parameter value + * + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +cdp_soc_set_param(ol_txrx_soc_handle soc, enum cdp_soc_param_t param, + uint32_t value) +{ + if (soc && soc->ops && soc->ops->cmn_drv_ops && + soc->ops->cmn_drv_ops->set_soc_param) + return soc->ops->cmn_drv_ops->set_soc_param(soc, param, + value); + + return QDF_STATUS_SUCCESS; +} + /* cdp_txrx_classify_and_update() - To classify the packet and update stats * @soc: opaque soc handle * @vdev: opaque dp vdev handle diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 4415508c47..3e1128cfa2 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -492,6 +492,10 @@ struct cdp_cmn_ops { uint32_t max_ast_index, bool peer_map_unmap_v2); + QDF_STATUS (*set_soc_param)(ol_txrx_soc_handle soc, + enum cdp_soc_param_t param, + uint32_t value); + ol_txrx_tx_fp tx_send; /** * txrx_get_os_rx_handles_from_vdev() - Return function, osif vdev diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index f27acb03f8..cc4545955e 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -1018,6 +1018,7 @@ struct cdp_rx_stats { * @clone_fail: NBUF clone failure * @dropped_pkt: Total scatter gather packets * @desc_na: Desc Not Available + * @exc_desc_na: Exception desc Not Available * @ring_full: ring full * @enqueue_fail: hw enqueue fail * @dma_error: dma fail @@ -1066,6 +1067,7 @@ struct cdp_tx_ingress_stats { struct { struct cdp_pkt_info dropped_pkt; struct cdp_pkt_info desc_na; + struct cdp_pkt_info exc_desc_na; uint32_t ring_full; uint32_t enqueue_fail; uint32_t dma_error; @@ -1736,6 +1738,11 @@ struct cdp_pdev_stats { uint64_t ppdu_drop; }; +enum cdp_soc_param_t { + DP_SOC_PARAM_MSDU_EXCEPTION_DESC, + DP_SOC_PARAM_MAX, +}; + #ifdef QCA_ENH_V3_STATS_SUPPORT /* * Enumeration of PDEV Configuration parameter diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index f464d63b93..3549b752a2 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -9358,6 +9358,26 @@ static QDF_STATUS dp_peer_map_attach_wifi3(struct cdp_soc_t *soc_hdl, return QDF_STATUS_SUCCESS; } +static QDF_STATUS dp_soc_set_param(struct cdp_soc_t *soc_hdl, + enum cdp_soc_param_t param, + uint32_t value) +{ + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + + switch (param) { + case DP_SOC_PARAM_MSDU_EXCEPTION_DESC: + soc->num_msdu_exception_desc = value; + dp_info("num_msdu exception_desc %u", + value); + break; + default: + dp_info("not handled param %d ", param); + break; + } + + return QDF_STATUS_SUCCESS; +} + static void dp_soc_set_rate_stats_ctx(struct cdp_soc_t *soc_handle, void *stats_ctx) { @@ -9697,6 +9717,7 @@ static struct cdp_cmn_ops dp_ops_cmn = { .txrx_peer_reset_ast_table = dp_wds_reset_ast_table_wifi3, .txrx_peer_flush_ast_table = dp_wds_flush_ast_table_wifi3, .txrx_peer_map_attach = dp_peer_map_attach_wifi3, + .set_soc_param = dp_soc_set_param, .txrx_get_os_rx_handles_from_vdev = dp_get_os_rx_handles_from_vdev_wifi3, .delba_tx_completion = dp_delba_tx_completion_wifi3, @@ -10729,6 +10750,7 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle, qdf_mem_zero(&soc->vdev_id_map, sizeof(soc->vdev_id_map)); qdf_atomic_init(&soc->num_tx_outstanding); + qdf_atomic_init(&soc->num_tx_exception); soc->num_tx_allowed = wlan_cfg_get_dp_soc_tx_device_limit(soc->wlan_cfg_ctx); diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 392864c46e..8574a3daf6 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -102,6 +102,30 @@ dp_tx_limit_check(struct dp_vdev *vdev) return false; } +/** + * dp_tx_exception_limit_check - Check if allocated tx exception descriptors + * reached soc max limit + * @vdev: DP vdev handle + * + * Return: true if allocated tx descriptors reached max configured value, else + * false + */ +static inline bool +dp_tx_exception_limit_check(struct dp_vdev *vdev) +{ + struct dp_pdev *pdev = vdev->pdev; + struct dp_soc *soc = pdev->soc; + + if (qdf_atomic_read(&soc->num_tx_exception) >= + soc->num_msdu_exception_desc) { + dp_info("exc packets are more than max drop the exc pkt"); + DP_STATS_INC(vdev, tx_i.dropped.exc_desc_na.num, 1); + return true; + } + + return false; +} + /** * dp_tx_outstanding_inc - Increment outstanding tx desc values on pdev and soc * @vdev: DP pdev handle @@ -139,6 +163,12 @@ dp_tx_limit_check(struct dp_vdev *vdev) return false; } +static inline bool +dp_tx_exception_limit_check(struct dp_vdev *vdev) +{ + return false; +} + static inline void dp_tx_outstanding_inc(struct dp_pdev *pdev) { @@ -274,7 +304,7 @@ dp_tx_desc_release(struct dp_tx_desc_s *tx_desc, uint8_t desc_pool_id) dp_tx_me_free_buf(tx_desc->pdev, tx_desc->me_buffer); if (tx_desc->flags & DP_TX_DESC_FLAG_TO_FW) - qdf_atomic_dec(&pdev->num_tx_exception); + qdf_atomic_dec(&soc->num_tx_exception); if (HAL_TX_COMP_RELEASE_SOURCE_TQM == hal_tx_comp_get_buffer_source(&tx_desc->comp)) @@ -681,7 +711,7 @@ struct dp_tx_ext_desc_elem_s *dp_tx_prepare_ext_desc(struct dp_vdev *vdev, qdf_mem_copy(&cached_ext_desc[HAL_TX_EXTENSION_DESC_LEN_BYTES], &msdu_info->meta_data[0], sizeof(struct htt_tx_msdu_desc_ext2_t)); - qdf_atomic_inc(&vdev->pdev->num_tx_exception); + qdf_atomic_inc(&soc->num_tx_exception); } switch (msdu_info->frm_type) { @@ -872,7 +902,7 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev, { /* Temporary WAR due to TQM VP issues */ tx_desc->flags |= DP_TX_DESC_FLAG_TO_FW; - qdf_atomic_inc(&pdev->num_tx_exception); + qdf_atomic_inc(&soc->num_tx_exception); } return tx_desc; @@ -942,7 +972,7 @@ static struct dp_tx_desc_s *dp_tx_prepare_desc(struct dp_vdev *vdev, #if TQM_BYPASS_WAR /* Temporary WAR due to TQM VP issues */ tx_desc->flags |= DP_TX_DESC_FLAG_TO_FW; - qdf_atomic_inc(&pdev->num_tx_exception); + qdf_atomic_inc(&soc->num_tx_exception); #endif if (qdf_unlikely(msdu_info->exception_fw)) tx_desc->flags |= DP_TX_DESC_FLAG_TO_FW; @@ -2212,6 +2242,12 @@ dp_tx_send_exception(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t nbuf, */ dp_tx_get_queue(vdev, nbuf, &msdu_info.tx_queue); + /* + * Check exception descriptors + */ + if (dp_tx_exception_limit_check(vdev)) + goto fail; + /* Single linear frame */ /* * If nbuf is a simple linear frame, use send_single function to @@ -4211,7 +4247,6 @@ QDF_STATUS dp_tx_pdev_init(struct dp_pdev *pdev) struct dp_soc *soc = pdev->soc; /* Initialize Flow control counters */ - qdf_atomic_init(&pdev->num_tx_exception); qdf_atomic_init(&pdev->num_tx_outstanding); if (wlan_cfg_per_pdev_tx_ring(soc->wlan_cfg_ctx)) { diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index dca6c94ed1..252ae5d7b4 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1300,6 +1300,8 @@ struct dp_soc { struct wlan_srng_cfg *wlan_srng_cfg; /* Num Tx outstanding on device */ qdf_atomic_t num_tx_outstanding; + /* Num Tx exception on device */ + qdf_atomic_t num_tx_exception; /* Num Tx allowed */ uint32_t num_tx_allowed; /* Preferred HW mode */ @@ -1336,6 +1338,8 @@ struct dp_soc { qdf_nbuf_t wbm_sg_nbuf_tail; uint32_t wbm_sg_desc_msdu_len; } wbm_sg_param; + /* Number of msdu exception descriptors */ + uint32_t num_msdu_exception_desc; }; #ifdef IPA_OFFLOAD diff --git a/target_if/init_deinit/src/init_event_handler.c b/target_if/init_deinit/src/init_event_handler.c index bb21d00844..de600c4dcd 100644 --- a/target_if/init_deinit/src/init_event_handler.c +++ b/target_if/init_deinit/src/init_event_handler.c @@ -198,6 +198,11 @@ static int init_deinit_service_ready_event_handler(ol_scn_t scn_handle, target_if_reg_set_offloaded_info(psoc); target_if_reg_set_6ghz_info(psoc); + /* Send num_msdu_desc to DP layer */ + cdp_soc_set_param(wlan_psoc_get_dp_handle(psoc), + DP_SOC_PARAM_MSDU_EXCEPTION_DESC, + tgt_hdl->info.target_caps.num_msdu_desc); + if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) { target_if_debug("Wait for EXT message"); } else {