Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a117325b authored by Yu Tian's avatar Yu Tian Committed by Madan Koyyalamudi
Browse files

qcacmn: Add a force TX ring HP flush when TX is pending

There is a timing race condition between RTPM suspend flow and
DP TX flow. When TX is queued during RTPM suspend flow. TX
ring update may be delayed. Add a force TX HP flush when RTPM
is rejected due to TX pending frame. This can help to improve
TX pending frames delay when race condition happens.

Change-Id: I6f60f2902dfda630f81528dcf978da6644d18ba7
CRs-Fixed: 2942744
parent b2f68a72
Loading
Loading
Loading
Loading
+32 −23
Original line number Diff line number Diff line
@@ -10520,6 +10520,29 @@ static struct cdp_cfr_ops dp_ops_cfr = {
#endif

#ifdef FEATURE_RUNTIME_PM
/**
 * dp_flush_ring_hptp() - Update ring shadow
 *			  register HP/TP address when runtime
 *                        resume
 * @opaque_soc: DP soc context
 *
 * Return: None
 */
static
void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng)
{
	if (hal_srng && hal_srng_get_clear_event(hal_srng,
						 HAL_SRNG_FLUSH_EVENT)) {
		/* Acquire the lock */
		hal_srng_access_start(soc->hal_soc, hal_srng);

		hal_srng_access_end(soc->hal_soc, hal_srng);

		hal_srng_set_flush_last_ts(hal_srng);
		dp_debug("flushed");
	}
}

/**
 * dp_runtime_suspend() - ensure DP is ready to runtime suspend
 * @soc_hdl: Datapath soc handle
@@ -10533,6 +10556,7 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
{
	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
	struct dp_pdev *pdev;
	uint8_t i;

	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
	if (!pdev) {
@@ -10544,6 +10568,14 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
	if (dp_get_tx_pending(dp_pdev_to_cdp_pdev(pdev)) > 0) {
		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
			  FL("Abort suspend due to pending TX packets"));

		/* perform a force flush if tx is pending */
		for (i = 0; i < soc->num_tcl_data_rings; i++) {
			hal_srng_set_event(soc->tcl_data_ring[i].hal_srng,
					   HAL_SRNG_FLUSH_EVENT);
			dp_flush_ring_hptp(soc, soc->tcl_data_ring[i].hal_srng);
		}

		return QDF_STATUS_E_AGAIN;
	}

@@ -10559,29 +10591,6 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
	return QDF_STATUS_SUCCESS;
}

/**
 * dp_flush_ring_hptp() - Update ring shadow
 *			  register HP/TP address when runtime
 *                        resume
 * @opaque_soc: DP soc context
 *
 * Return: None
 */
static
void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng)
{
	if (hal_srng && hal_srng_get_clear_event(hal_srng,
						 HAL_SRNG_FLUSH_EVENT)) {
		/* Acquire the lock */
		hal_srng_access_start(soc->hal_soc, hal_srng);

		hal_srng_access_end(soc->hal_soc, hal_srng);

		hal_srng_set_flush_last_ts(hal_srng);
		dp_debug("flushed");
	}
}

#define DP_FLUSH_WAIT_CNT 10
#define DP_RUNTIME_SUSPEND_WAIT_MS 10
/**