From a4b2a032006aa5829fd37009d2621fdc7b5ffcfa Mon Sep 17 00:00:00 2001 From: Ananya Gupta Date: Tue, 20 Sep 2022 12:20:07 +0530 Subject: [PATCH] qcacmn: Pause Tx HW enqueue when bus suspend in progress In SAP due to intrabss forwarding, Tx ring update is going through when WOW enable command has been sent to FW. This results in crash. To fix this, do not update HP when apps suspend is in progress. Change-Id: Id4176224563bdd759828397fa1cd23de1598192e CRs-Fixed: 3294407 --- dp/inc/cdp_txrx_cmn.h | 23 +++++++++++++++++++++++ dp/inc/cdp_txrx_ops.h | 2 ++ dp/wifi3.0/dp_main.c | 16 ++++++++++++++++ dp/wifi3.0/dp_tx.c | 6 ++++-- dp/wifi3.0/dp_types.h | 1 + 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index f3b6921c20..7a5fb78df1 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -2083,6 +2083,29 @@ cdp_txrx_set_pdev_status_down(ol_txrx_soc_handle soc, is_pdev_down); } +/** + * cdp_set_tx_pause() - Pause or resume tx path + * @soc_hdl: Datapath soc handle + * @flag: set or clear is_tx_pause + * + * Return: None. + */ +static inline +void cdp_set_tx_pause(ol_txrx_soc_handle soc, bool flag) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance:"); + QDF_BUG(0); + return; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->set_tx_pause) + return; + + soc->ops->cmn_drv_ops->set_tx_pause(soc, flag); +} + /** * cdp_tx_send() - enqueue frame for transmission * @soc: soc opaque handle diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 50da1ac4c8..4cd6104bf7 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -595,6 +595,8 @@ struct cdp_cmn_ops { */ ol_txrx_tx_fast_fp tx_fast_send; + void (*set_tx_pause)(ol_txrx_soc_handle soc, bool flag); + /** * txrx_get_os_rx_handles_from_vdev() - Return function, osif vdev * to deliver pkt to stack. diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index b8dff26096..09d2dd224d 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -13578,6 +13578,21 @@ dp_get_tsf_time(struct cdp_soc_t *soc_hdl, uint32_t tsf_id, uint32_t mac_id, } #endif +/** + * dp_set_tx_pause() - Pause or resume tx path + * @soc_hdl: Datapath soc handle + * @flag: set or clear is_tx_pause + * + * Return: None. + */ +static inline +void dp_set_tx_pause(struct cdp_soc_t *soc_hdl, bool flag) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + + soc->is_tx_pause = flag; +} + static struct cdp_cmn_ops dp_ops_cmn = { .txrx_soc_attach_target = dp_soc_attach_target_wifi3, .txrx_vdev_attach = dp_vdev_attach_wifi3, @@ -13616,6 +13631,7 @@ static struct cdp_cmn_ops dp_ops_cmn = { .tx_send = dp_tx_send, .tx_send_exc = dp_tx_send_exception, #endif + .set_tx_pause = dp_set_tx_pause, .txrx_pdev_init = dp_pdev_init_wifi3, .txrx_get_vdev_mac_addr = dp_get_vdev_mac_addr_wifi3, .txrx_get_ctrl_pdev_from_vdev = dp_get_ctrl_pdev_from_vdev_wifi3, diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index e6756ccb87..faff72dcad 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -1631,7 +1631,8 @@ dp_tx_ring_access_end_wrapper(struct dp_soc *soc, ret = hif_rtpm_get(HIF_RTPM_GET_ASYNC, HIF_RTPM_ID_DP); if (QDF_IS_STATUS_SUCCESS(ret)) { - if (hif_system_pm_state_check(soc->hif_handle)) { + if (hif_system_pm_state_check(soc->hif_handle) || + qdf_unlikely(soc->is_tx_pause)) { dp_tx_hal_ring_access_end_reap(soc, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); hal_srng_inc_flush_cnt(hal_ring_hdl); @@ -1656,7 +1657,8 @@ dp_tx_ring_access_end_wrapper(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl, int coalesce) { - if (hif_system_pm_state_check(soc->hif_handle)) { + if (hif_system_pm_state_check(soc->hif_handle) || + qdf_unlikely(soc->is_tx_pause)) { dp_tx_hal_ring_access_end_reap(soc, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); hal_srng_inc_flush_cnt(hal_ring_hdl); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 4fb06bebf8..bc3cc46caa 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -2564,6 +2564,7 @@ struct dp_soc { /* A flag using to decide the switch of rx link speed */ bool high_throughput; #endif + bool is_tx_pause; }; #ifdef IPA_OFFLOAD