qcacmn: Fix long ping delay after enable RTPM

Issue1: Driver RTPM state is ON/NONE, Kernel state is RESUMING.
cdp_runtime_resume is already complete,
hif_pm_runtime_get return -E_INPROGRESS,
dp_tx_hw_enqueue will set the flush event,
but cdp_runtime_resume is already done,
this flush event will be handled only on next pkt tx.

Issue2: Driver RTPM state: Resuming
hif_pm_runtime_get returns -EBUSY,
dp_tx_hw_enqueue is interrupted by any IRQ,
cdp_runtime_resume is completed,
dp_tx_hw_enqueue will set the flush event,
This flush event will be handled only on next pkt tx.

Fix:
Introduce a link_state_up atomic variable in hif to track the link state
change by pld_cb.
Set atomic variable link_state_up=1 in pmo_core_psoc_bus_runtime_resume
just after pld_cb. pld_cb brings the PCIe bus out of suspend state.
Set atomic variable link_state_up=0 in pmo_core_psoc_bus_runtime_suspend
just before pld_cb. pld_cb puts the PCIe bus into suspend state.

Introduce dp_runtime_get and dp_runtime_put.
dp_runtime_get get refcount with increment of an atomic variable.
dp_runtime_put return refcount with decrement of  this atomic variable.

If hif_pm_runtime_get returns -EBUSY or -EINPROGRESS,
take the dp runtime refcount using dp_runtime_get,
check if the link state is up, write TX ring HP,
return the dp runtime refcount using dp_runtime_put.

cdp_runtime_suspend should reject the suspend, if dp_runtime_get is non
zero.
cdp_runtime_resume should wait until dp_runtime_get becomes zero or time
out, then flush pending tx for runtime suspend.

Change-Id: I5b97d50cba710082f117f3845f7830712b86cda7
CRs-Fixed: 2844888
此提交包含在:
Jianmin Zhu
2021-01-09 13:01:37 +08:00
提交者 snandini
父節點 1e157ef978
當前提交 6ef2047d56
共有 8 個檔案被更改,包括 214 行新增12 行删除

查看文件

@@ -5375,6 +5375,8 @@ dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc)
DP_STATS_INIT(soc);
dp_runtime_init(soc);
/* initialize work queue for stats processing */
qdf_create_work(0, &soc->htt_stats.work, htt_t2h_stats_handler, soc);
@@ -11422,6 +11424,12 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
return QDF_STATUS_E_AGAIN;
}
if (dp_runtime_get_refcount(soc)) {
dp_init_info("refcount: %d", dp_runtime_get_refcount(soc));
return QDF_STATUS_E_AGAIN;
}
if (soc->intr_mode == DP_INTR_POLL)
qdf_timer_stop(&soc->int_timer);
@@ -11449,9 +11457,12 @@ void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t 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
/**
* dp_runtime_resume() - ensure DP is ready to runtime resume
* @soc_hdl: Datapath soc handle
@@ -11464,11 +11475,21 @@ void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng)
static QDF_STATUS dp_runtime_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
{
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
int i;
int i, suspend_wait = 0;
if (soc->intr_mode == DP_INTR_POLL)
qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
/*
* Wait until dp runtime refcount becomes zero or time out, then flush
* pending tx for runtime suspend.
*/
while (dp_runtime_get_refcount(soc) &&
suspend_wait < DP_FLUSH_WAIT_CNT) {
qdf_sleep(DP_RUNTIME_SUSPEND_WAIT_MS);
suspend_wait++;
}
for (i = 0; i < MAX_TCL_DATA_RINGS; i++) {
dp_flush_ring_hptp(soc, soc->tcl_data_ring[i].hal_srng);
}