From b96e5072de79d147d85bcb552a5c8656b9ea9c16 Mon Sep 17 00:00:00 2001 From: Sravan Kumar Kairam Date: Wed, 21 Aug 2019 20:59:51 +0530 Subject: [PATCH] qcacmn: Add runtime pm apis to record last dp rx busy mark Add runtime pm apis to record last busy mark set by data path during dp rx process. Currently for mcl in some scenerios runtime sync suspend is issued which puts the link in low power state with out waiting for link inactivity timeout. This leads to throughput degradation in case of rx direction as in rx processing data path extends the timer by marking last busy to avoid immediate runtime suspend. But runtime sync suspend does not take in to account of the link idle timeout value before suspending the link. So using this apis, before issuing runtime sync suspend check the duration since last busy mark by data path rx process. If the duration is less than run time delay just do runtime put. Change-Id: I694ef6ddec8f11fed44bf3b9e5ae18ad93b6ec24 CRs-Fixed: 2512326 --- dp/wifi3.0/dp_rx.c | 2 +- hif/inc/hif.h | 11 +++++++++ hif/src/pcie/if_pci.c | 55 +++++++++++++++++++++++++++++++++++++++++++ hif/src/pcie/if_pci.h | 2 ++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index b9b79b4b65..6d6e94d3c0 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -1697,7 +1697,7 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, hal_ring_handle_t hal_ring_hdl, qdf_assert_always(hal_soc); scn = soc->hif_handle; - hif_pm_runtime_mark_last_busy(scn); + hif_pm_runtime_mark_dp_rx_busy(scn); intr_id = int_ctx->dp_intr_id; more_data: diff --git a/hif/inc/hif.h b/hif/inc/hif.h index d24f0cac09..1995c2382a 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -865,6 +865,9 @@ bool hif_pm_runtime_is_suspended(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_get_monitor_wake_intr(struct hif_opaque_softc *hif_ctx); void hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx, int val); +void hif_pm_runtime_mark_dp_rx_busy(struct hif_opaque_softc *hif_ctx); +int hif_pm_runtime_is_dp_rx_busy(struct hif_opaque_softc *hif_ctx); +qdf_time_t hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx); #else struct hif_pm_runtime_lock { const char *name; @@ -912,6 +915,14 @@ hif_pm_runtime_get_monitor_wake_intr(struct hif_opaque_softc *hif_ctx) static inline void hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx, int val) { return; } +static inline void +hif_pm_runtime_mark_dp_rx_busy(struct hif_opaque_softc *hif_ctx) {}; +static inline int +hif_pm_runtime_is_dp_rx_busy(struct hif_opaque_softc *hif_ctx) +{ return 0; } +static inline qdf_time_t +hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx) +{ return 0; } #endif void hif_enable_power_management(struct hif_opaque_softc *hif_ctx, diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c index f4d7a086fe..732fc9bcd2 100644 --- a/hif/src/pcie/if_pci.c +++ b/hif/src/pcie/if_pci.c @@ -2856,6 +2856,7 @@ void hif_process_runtime_resume_success(struct hif_opaque_softc *hif_ctx) */ int hif_runtime_suspend(struct hif_opaque_softc *hif_ctx) { + struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); int errno; errno = hif_bus_suspend(hif_ctx); @@ -2873,6 +2874,8 @@ int hif_runtime_suspend(struct hif_opaque_softc *hif_ctx) goto bus_resume; } + qdf_atomic_set(&sc->pm_dp_rx_busy, 0); + return 0; bus_resume: @@ -4522,6 +4525,58 @@ void hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx, qdf_atomic_set(&sc->monitor_wake_intr, val); } + +/** + * hif_pm_runtime_mark_dp_rx_busy() - Set last busy mark my data path + * @hif_ctx: HIF context + * + * Return: void + */ +void hif_pm_runtime_mark_dp_rx_busy(struct hif_opaque_softc *hif_ctx) +{ + struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); + + if (!sc) + return; + + qdf_atomic_set(&sc->pm_dp_rx_busy, 1); + sc->dp_last_busy_timestamp = qdf_get_log_timestamp_usecs(); + + hif_pm_runtime_mark_last_busy(hif_ctx); +} + +/** + * hif_pm_runtime_is_dp_rx_busy() - Check if last mark busy by dp rx + * @hif_ctx: HIF context + * + * Return: dp rx busy set value + */ +int hif_pm_runtime_is_dp_rx_busy(struct hif_opaque_softc *hif_ctx) +{ + struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); + + if (!sc) + return 0; + + return qdf_atomic_read(&sc->pm_dp_rx_busy); +} + +/** + * hif_pm_runtime_get_dp_rx_busy_mark() - Get last busy by dp rx timestamp + * @hif_ctx: HIF context + * + * Return: timestamp of last mark busy by dp rx + */ +qdf_time_t hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx) +{ + struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx); + + if (!sc) + return 0; + + return sc->dp_last_busy_timestamp; +} + #endif /* FEATURE_RUNTIME_PM */ int hif_pci_legacy_map_ce_to_irq(struct hif_softc *scn, int ce_id) diff --git a/hif/src/pcie/if_pci.h b/hif/src/pcie/if_pci.h index 2f2516ed29..68109291d6 100644 --- a/hif/src/pcie/if_pci.h +++ b/hif/src/pcie/if_pci.h @@ -141,6 +141,8 @@ struct hif_pci_softc { struct list_head prevent_suspend_list; unsigned long runtime_timer_expires; qdf_runtime_lock_t prevent_linkdown_lock; + atomic_t pm_dp_rx_busy; + qdf_time_t dp_last_busy_timestamp; #ifdef WLAN_OPEN_SOURCE struct dentry *pm_dentry; #endif