|
@@ -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 */
|
|
/* Threshold for peer's cached buf queue beyond which frames are dropped */
|
|
#define DP_RX_CACHED_BUFQ_THRESH 64
|
|
#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
|
|
* 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
|
|
|
|
- * reqd as we are not getting ppdu end interrupts
|
|
|
|
- * @arg: SoC Handle
|
|
|
|
|
|
+ * dp_service_mon_rings()- service monitor rings
|
|
|
|
+ * @soc: soc dp handle
|
|
|
|
+ * @quota: number of ring entry that can be serviced
|
|
*
|
|
*
|
|
- * Return:
|
|
|
|
|
|
+ * Return: None
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
-static void dp_service_mon_rings(void *arg)
|
|
|
|
|
|
+static void dp_service_mon_rings(struct dp_soc *soc, uint32_t quota)
|
|
{
|
|
{
|
|
- struct dp_soc *soc = (struct dp_soc *)arg;
|
|
|
|
int ring = 0, work_done;
|
|
int ring = 0, work_done;
|
|
struct dp_pdev *pdev = NULL;
|
|
struct dp_pdev *pdev = NULL;
|
|
|
|
|
|
- for (ring = 0 ; ring < MAX_NUM_LMAC_HW; ring++) {
|
|
|
|
|
|
+ for (ring = 0 ; ring < MAX_NUM_LMAC_HW; ring++) {
|
|
pdev = dp_get_pdev_for_lmac_id(soc, ring);
|
|
pdev = dp_get_pdev_for_lmac_id(soc, ring);
|
|
if (!pdev)
|
|
if (!pdev)
|
|
continue;
|
|
continue;
|
|
- work_done = dp_mon_process(soc, ring,
|
|
|
|
- QCA_NAPI_BUDGET);
|
|
|
|
|
|
+ work_done = dp_mon_process(soc, ring, quota);
|
|
|
|
|
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
FL("Reaped %d descs from Monitor rings"),
|
|
FL("Reaped %d descs from Monitor rings"),
|
|
work_done);
|
|
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_mon_reap_timer_handler(void *arg)
|
|
|
|
+{
|
|
|
|
+ struct dp_soc *soc = (struct dp_soc *)arg;
|
|
|
|
+
|
|
|
|
+ dp_service_mon_rings(soc, QCA_NAPI_BUDGET);
|
|
|
|
|
|
qdf_timer_mod(&soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
|
|
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
|
|
* Needed until we enable ppdu end interrupts
|
|
*/
|
|
*/
|
|
qdf_timer_init(soc->osdev, &soc->mon_reap_timer,
|
|
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;
|
|
soc->reap_timer_init = 1;
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
@@ -10676,8 +10692,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)
|
|
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 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 timeout = SUSPEND_DRAIN_WAIT;
|
|
int drain_wait_delay = 50; /* 50 ms */
|
|
int drain_wait_delay = 50; /* 50 ms */
|
|
|
|
|
|
@@ -10687,7 +10702,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 */
|
|
/* 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);
|
|
qdf_sleep(drain_wait_delay);
|
|
if (timeout <= 0) {
|
|
if (timeout <= 0) {
|
|
dp_err("TX frames are pending, abort suspend");
|
|
dp_err("TX frames are pending, abort suspend");
|
|
@@ -10699,22 +10714,70 @@ static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
|
|
if (soc->intr_mode == DP_INTR_POLL)
|
|
if (soc->intr_mode == DP_INTR_POLL)
|
|
qdf_timer_stop(&soc->int_timer);
|
|
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;
|
|
return QDF_STATUS_SUCCESS;
|
|
}
|
|
}
|
|
|
|
|
|
static QDF_STATUS dp_bus_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
|
|
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_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)
|
|
if (soc->intr_mode == DP_INTR_POLL)
|
|
qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
|
|
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;
|
|
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 = {
|
|
static struct cdp_bus_ops dp_ops_bus = {
|
|
.bus_suspend = dp_bus_suspend,
|
|
.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
|
|
#endif
|
|
|
|
|