qcacmn: Stop the monitor reap timer at dp suspend

In case of wlan suspend if packet log is enabled stop the
monitor reap timer and reap the pending frames in the ring.
Also in case of FW target suspend ACK status reap monitor
status ring. During target suspend FW will disable the monitor
status ring. This change will make sure no pending frames in
the ring during start of system suspend and the target suspend.

Change-Id: I350fa508f3ddd125d5e00a7fc60e89507ce8fb4e
CRs-Fixed: 2604389
This commit is contained in:
Sravan Goud
2020-01-22 21:24:11 +05:30
parent b1261d4e0c
commit 37c06b57a3
3 changed files with 110 additions and 22 deletions

View File

@@ -201,6 +201,9 @@ static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc,
/* Threshold for peer's cached buf queue beyond which frames are dropped */
#define DP_RX_CACHED_BUFQ_THRESH 64
/* Budget to reap monitor status ring */
#define DP_MON_REAP_BUDGET 1024
/**
* default_dscp_tid_map - Default DSCP-TID mapping
*
@@ -338,30 +341,43 @@ uint32_t dp_soc_get_mon_mask_for_interrupt_mode(struct dp_soc *soc, int intr_ctx
}
/*
* dp_service_mon_rings()- timer to reap monitor rings
* dp_service_mon_rings()- service monitor rings
* @soc: soc dp handle
* @quota: number of ring entry that can be serviced
*
* Return: None
*
*/
static void dp_service_mon_rings(struct dp_soc *soc, uint32_t quota)
{
int ring = 0, work_done;
struct dp_pdev *pdev = NULL;
for (ring = 0 ; ring < MAX_NUM_LMAC_HW; ring++) {
pdev = dp_get_pdev_for_lmac_id(soc, ring);
if (!pdev)
continue;
work_done = dp_mon_process(soc, ring, quota);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
FL("Reaped %d descs from Monitor rings"),
work_done);
}
}
/*
* dp_mon_reap_timer_handler()- timer to reap monitor rings
* reqd as we are not getting ppdu end interrupts
* @arg: SoC Handle
*
* Return:
*
*/
static void dp_service_mon_rings(void *arg)
static void dp_mon_reap_timer_handler(void *arg)
{
struct dp_soc *soc = (struct dp_soc *)arg;
int ring = 0, work_done;
struct dp_pdev *pdev = NULL;
for (ring = 0 ; ring < MAX_NUM_LMAC_HW; ring++) {
pdev = dp_get_pdev_for_lmac_id(soc, ring);
if (!pdev)
continue;
work_done = dp_mon_process(soc, ring,
QCA_NAPI_BUDGET);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
FL("Reaped %d descs from Monitor rings"),
work_done);
}
dp_service_mon_rings(soc, QCA_NAPI_BUDGET);
qdf_timer_mod(&soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
}
@@ -4670,8 +4686,8 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc)
* Needed until we enable ppdu end interrupts
*/
qdf_timer_init(soc->osdev, &soc->mon_reap_timer,
dp_service_mon_rings, (void *)soc,
QDF_TIMER_TYPE_WAKE_APPS);
dp_mon_reap_timer_handler, (void *)soc,
QDF_TIMER_TYPE_WAKE_APPS);
soc->reap_timer_init = 1;
return status;
}
@@ -10666,8 +10682,7 @@ static struct cdp_ipa_ops dp_ops_ipa = {
static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
{
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
struct cdp_pdev *pdev = (struct cdp_pdev *)
dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
int timeout = SUSPEND_DRAIN_WAIT;
int drain_wait_delay = 50; /* 50 ms */
@@ -10677,7 +10692,7 @@ static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
}
/* Abort if there are any pending TX packets */
while (dp_get_tx_pending(pdev) > 0) {
while (dp_get_tx_pending((struct cdp_pdev *)pdev) > 0) {
qdf_sleep(drain_wait_delay);
if (timeout <= 0) {
dp_err("TX frames are pending, abort suspend");
@@ -10689,22 +10704,70 @@ static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
if (soc->intr_mode == DP_INTR_POLL)
qdf_timer_stop(&soc->int_timer);
/* Stop monitor reap timer and reap any pending frames in ring */
if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED &&
soc->reap_timer_init) {
qdf_timer_sync_cancel(&soc->mon_reap_timer);
dp_service_mon_rings(soc, DP_MON_REAP_BUDGET);
}
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS dp_bus_resume(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 = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
if (qdf_unlikely(!pdev)) {
dp_err("pdev is NULL");
return QDF_STATUS_E_INVAL;
}
if (soc->intr_mode == DP_INTR_POLL)
qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
/* Start monitor reap timer */
if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED &&
soc->reap_timer_init)
qdf_timer_mod(&soc->mon_reap_timer,
DP_INTR_POLL_TIMER_MS);
return QDF_STATUS_SUCCESS;
}
/**
* dp_process_wow_ack_rsp() - process wow ack response
* @soc_hdl: datapath soc handle
* @pdev_id: data path pdev handle id
*
* Return: none
*/
static void dp_process_wow_ack_rsp(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 = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
if (qdf_unlikely(!pdev)) {
dp_err("pdev is NULL");
return;
}
/*
* As part of wow enable FW disables the mon status ring and in wow ack
* response from FW reap mon status ring to make sure no packets pending
* in the ring.
*/
if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED &&
soc->reap_timer_init) {
dp_service_mon_rings(soc, DP_MON_REAP_BUDGET);
}
}
static struct cdp_bus_ops dp_ops_bus = {
.bus_suspend = dp_bus_suspend,
.bus_resume = dp_bus_resume
.bus_resume = dp_bus_resume,
.process_wow_ack_rsp = dp_process_wow_ack_rsp,
};
#endif