From 1ce2688f28c82874ea411aa1b39d2dd60b6b668f Mon Sep 17 00:00:00 2001 From: Surabhi Vishnoi Date: Tue, 19 May 2020 10:41:23 +0530 Subject: [PATCH] qcacld-3.0: Add handler for WMI_VDEV_BCN_LATENCY_EVENTID WMI_VDEV_BCN_LATENCY_EVENTID is sent by firmware when it receives the latency IE from connected AP in beacon. Add handler for this event and when latency_level received is ultra low in latency IE, update request pm qos type PM_QOS_CPU_DMA_LATENCY to level DISABLE_KRAIT_IDLE_PS_VAL to speed up CPU efficiency and irq response. This is needed for Voice and Music products where extreme low latency is needed while playing music and high power consumption is accepted. Change-Id: I3c63ef247f4f4a1add68111ef1bcee6daafd148a CRs-Fixed: 2723205 --- core/hdd/inc/wlan_hdd_main.h | 14 ++++++++++++ core/hdd/src/wlan_hdd_main.c | 19 +++++++++++++++++ core/sme/inc/sme_api.h | 22 +++++++++++++++++++ core/sme/inc/sme_internal.h | 3 +++ core/sme/src/common/sme_api.c | 21 ++++++++++++++++++ core/wma/inc/wma_internal.h | 20 ++++++++++++++++++ core/wma/src/wma_features.c | 40 +++++++++++++++++++++++++++++++++++ core/wma/src/wma_main.c | 6 ++++++ 8 files changed, 145 insertions(+) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 6f2248f623..f8dd1a4685 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -4484,4 +4484,18 @@ int hdd_update_phymode(struct hdd_adapter *adapter, eCsrPhyMode phymode, */ bool hdd_max_sta_vdev_count_reached(struct hdd_context *hdd_ctx); +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +/** + * hdd_beacon_latency_event_cb() - Callback function to get latency level + * @latency_level: latency level received from firmware + * + * Return: None + */ +void hdd_beacon_latency_event_cb(uint32_t latency_level); +#else +static inline void hdd_beacon_latency_event_cb(uint32_t latency_level) +{ +} +#endif + #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index c47152b40e..e2f67a4869 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -14223,6 +14223,11 @@ int hdd_register_cb(struct hdd_context *hdd_ctx) if (QDF_IS_STATUS_ERROR(status)) hdd_err_rl("Register monitor mode callback failed"); + status = sme_set_beacon_latency_event_cb(mac_handle, + hdd_beacon_latency_event_cb); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err_rl("Register beacon latency event callback failed"); + hdd_exit(); return ret; @@ -17760,6 +17765,20 @@ free: return ret; } +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +void hdd_beacon_latency_event_cb(uint32_t latency_level) +{ + struct hdd_context *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + hdd_err_rl("Invalid HDD_CTX"); + return; + } + wlan_hdd_set_wlm_mode(hdd_ctx, latency_level); +} +#endif + #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2) { diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index cba9c04a28..cb2af46fcd 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -4223,4 +4223,26 @@ sme_process_monitor_mode_vdev_up_evt(uint8_t vdev_id) } #endif +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +/** + * sme_set_beacon_latency_event_cb() - Register beacon latency IE callback + * @mac_handle: Opaque handle to the MAC context + * @beacon_latency_event_cb: callback to be registered + * + * Return: QDF_STATUS + */ +QDF_STATUS +sme_set_beacon_latency_event_cb(mac_handle_t mac_handle, + void (*beacon_latency_event_cb) + (uint32_t latency_level)); +#else +static inline QDF_STATUS +sme_set_beacon_latency_event_cb(mac_handle_t mac_handle, + void (*beacon_latency_event_cb) + (uint32_t latency_level)) +{ + return QDF_STATUS_SUCCESS; +} +#endif + #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index b186a87fd8..498069dc65 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -389,6 +389,9 @@ struct sme_context { #ifdef FEATURE_MONITOR_MODE_SUPPORT void (*monitor_mode_cb)(uint8_t vdev_id); #endif +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) + void (*beacon_latency_event_cb)(uint32_t latency_level); +#endif }; #endif /* #if !defined( __SMEINTERNAL_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 4b4e4f1c61..5fbed0c3f8 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -16263,3 +16263,24 @@ QDF_STATUS sme_process_monitor_mode_vdev_up_evt(uint8_t vdev_id) return QDF_STATUS_SUCCESS; } #endif + +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +QDF_STATUS +sme_set_beacon_latency_event_cb(mac_handle_t mac_handle, + void (*beacon_latency_event_cb) + (uint32_t latency_level)) +{ + QDF_STATUS qdf_status; + struct mac_context *mac = MAC_CONTEXT(mac_handle); + + qdf_status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(qdf_status)) { + sme_err("Failed to acquire sme lock; status: %d", qdf_status); + return qdf_status; + } + mac->sme.beacon_latency_event_cb = beacon_latency_event_cb; + sme_release_global_lock(&mac->sme); + + return qdf_status; +} +#endif diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 3ac9b69120..c11defd6bb 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1499,6 +1499,26 @@ int wma_unified_beacon_debug_stats_event_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +/** + * wma_vdev_bcn_latency_event_handler() - Get the latency info received in bcn + * @handle: WMA handle + * @event: data in event + * @len: length + * + * Return: 0 for success or error code + */ +int wma_vdev_bcn_latency_event_handler(void *handle, uint8_t *event, + uint32_t len); +#else +static inline int wma_vdev_bcn_latency_event_handler(void *handle, + uint8_t *event, + uint32_t len) +{ + return 0; +} +#endif + #ifdef FEATURE_WLAN_DIAG_SUPPORT /** * wma_sta_kickout_event()- send sta kickout event diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index fcf765af53..4fae932594 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -4705,6 +4705,46 @@ int wma_unified_beacon_debug_stats_event_handler(void *handle, } #endif +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +int +wma_vdev_bcn_latency_event_handler(void *handle, + uint8_t *event_info, + uint32_t len) +{ + WMI_VDEV_BCN_LATENCY_EVENTID_param_tlvs *param_buf = NULL; + wmi_vdev_bcn_latency_fixed_param *bcn_latency = NULL; + struct mac_context *mac = + (struct mac_context *)cds_get_context(QDF_MODULE_ID_PE); + uint32_t latency_level; + + param_buf = (WMI_VDEV_BCN_LATENCY_EVENTID_param_tlvs *)event_info; + if (!param_buf) { + wma_err("Invalid bcn latency event"); + return -EINVAL; + } + + bcn_latency = param_buf->fixed_param; + if (!bcn_latency) { + wma_debug("beacon latency event fixed param is NULL"); + return -EINVAL; + } + + /* Map the latency value to the level which host expects + * 1 - normal, 2 - moderate, 3 - low, 4 - ultralow + */ + latency_level = bcn_latency->latency_level + 1; + if (latency_level < 1 || latency_level > 4) { + wma_debug("invalid beacon latency level value"); + return -EINVAL; + } + + /* Call the registered sme callback */ + mac->sme.beacon_latency_event_cb(latency_level); + + return 0; +} +#endif + int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, uint32_t len) { diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 1437061160..8c3c01dd50 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -3134,6 +3134,12 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, WMA_RX_SERIALIZER_CTX); #endif +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) + wmi_unified_register_event_handler(wma_handle->wmi_handle, + wmi_vdev_bcn_latency_event_id, + wma_vdev_bcn_latency_event_handler, + WMA_RX_SERIALIZER_CTX); +#endif /* register for linkspeed response event */ wmi_unified_register_event_handler(wma_handle->wmi_handle, wmi_peer_estimated_linkspeed_event_id,