diff --git a/core/hdd/inc/wlan_hdd_tx_rx.h b/core/hdd/inc/wlan_hdd_tx_rx.h index 46885c370a0e..f358c41dac84 100644 --- a/core/hdd/inc/wlan_hdd_tx_rx.h +++ b/core/hdd/inc/wlan_hdd_tx_rx.h @@ -449,4 +449,14 @@ void hdd_print_netdev_txq_status(struct net_device *dev); uint32_t wlan_hdd_dump_queue_history_state(struct hdd_netif_queue_history *q_hist, char *buf, uint32_t size); + +/** + * wlan_hdd_rx_rpm_mark_last_busy() - Check if dp rx marked last busy + * @hdd_ctx: Pointer to hdd context + * @hif_ctx: Pointer to hif context + * + * Return: dp mark last busy less than runtime delay value + */ +bool wlan_hdd_rx_rpm_mark_last_busy(struct hdd_context *hdd_ctx, + void *hif_ctx); #endif /* end #if !defined(WLAN_HDD_TX_RX_H) */ diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index 3d5558071766..e2417c214c41 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -4672,16 +4672,24 @@ static int _wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, const uint8_t *mac, struct station_info *sinfo) { + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); int errno; + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno) + return errno; + errno = hif_pm_runtime_get_sync(hif_ctx); if (errno) return errno; errno = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo); - hif_pm_runtime_put_sync_suspend(hif_ctx); + if (wlan_hdd_rx_rpm_mark_last_busy(hdd_ctx, hif_ctx)) + hif_pm_runtime_put(hif_ctx); + else + hif_pm_runtime_put_sync_suspend(hif_ctx); return errno; } diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index 757b36022151..949ee32b9ceb 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -3106,3 +3106,24 @@ void hdd_dp_cfg_update(struct wlan_objmgr_psoc *psoc, hdd_dp_dp_trace_cfg_update(config, psoc); hdd_dp_nud_tracking_cfg_update(config, psoc); } + +bool wlan_hdd_rx_rpm_mark_last_busy(struct hdd_context *hdd_ctx, + void *hif_ctx) +{ + uint64_t duration_us, dp_rx_busy_us, current_us; + uint32_t rpm_delay_ms; + + if (!hif_pm_runtime_is_dp_rx_busy(hif_ctx)) + return false; + + dp_rx_busy_us = hif_pm_runtime_get_dp_rx_busy_mark(hif_ctx); + current_us = qdf_get_log_timestamp_usecs(); + duration_us = (unsigned long)((ULONG_MAX - dp_rx_busy_us) + + current_us + 1); + rpm_delay_ms = ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc); + + if ((duration_us / 1000) < rpm_delay_ms) + return true; + else + return false; +}