diff --git a/Kbuild b/Kbuild index e04a21207b..9726e129c5 100644 --- a/Kbuild +++ b/Kbuild @@ -4119,8 +4119,14 @@ endif # Enable feature sync tsf for chips based on Adrastea arch ccflags-$(CONFIG_WLAN_SYNC_TSF_PLUS_NOIRQ) += -DWLAN_FEATURE_TSF_PLUS_NOIRQ +ifeq ($(CONFIG_WLAN_TSF_UPLINK_DELAY), y) # Enable uplink delay report feature -ccflags-$(CONFIG_WLAN_TSF_UPLINK_DELAY) += -DWLAN_FEATURE_TSF_UPLINK_DELAY +ccflags-y += -DWLAN_FEATURE_TSF_UPLINK_DELAY +CONFIG_WLAN_TSF_AUTO_REPORT := y +endif + +# Enable TSF auto report feature +ccflags-$(CONFIG_WLAN_TSF_AUTO_REPORT) += -DWLAN_FEATURE_TSF_AUTO_REPORT ccflags-$(CONFIG_ATH_PROCFS_DIAG_SUPPORT) += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT diff --git a/Kconfig b/Kconfig index d2bf7ef308..590e1dcb34 100644 --- a/Kconfig +++ b/Kconfig @@ -1619,8 +1619,13 @@ config WLAN_TRACEPOINTS bool "Enable WLAN_TRACEPOINTS" default n +config WLAN_TSF_AUTO_REPORT + bool "Enable WLAN_TSF_AUTO_REPORT" + default n + config WLAN_TSF_UPLINK_DELAY bool "Enable WLAN_TSF_UPLINK_DELAY" + depends on WLAN_TSF_AUTO_REPORT default n config WLAN_TWT_CONVERGED diff --git a/configs/config_to_feature.h b/configs/config_to_feature.h index ef55e94ec5..00a0c6d873 100644 --- a/configs/config_to_feature.h +++ b/configs/config_to_feature.h @@ -1328,6 +1328,10 @@ #define WLAN_FEATURE_TSF_PLUS_NOIRQ (1) #endif +#ifdef CONFIG_WLAN_TSF_AUTO_REPORT +#define WLAN_FEATURE_TSF_AUTO_REPORT (1) +#endif + #ifdef CONFIG_WLAN_TSF_UPLINK_DELAY #define WLAN_FEATURE_TSF_UPLINK_DELAY (1) #endif diff --git a/configs/pineapple_gki_kiwi-v2_defconfig b/configs/pineapple_gki_kiwi-v2_defconfig index de54020de4..74b07959fe 100644 --- a/configs/pineapple_gki_kiwi-v2_defconfig +++ b/configs/pineapple_gki_kiwi-v2_defconfig @@ -331,6 +331,7 @@ CONFIG_WLAN_SYSFS_BITRATES=y CONFIG_WLAN_THERMAL_CFG=y CONFIG_WLAN_THERMAL_MULTI_CLIENT_SUPPORT=y CONFIG_WLAN_TRACEPOINTS=y +CONFIG_WLAN_TSF_AUTO_REPORT=y CONFIG_WLAN_TSF_UPLINK_DELAY=y CONFIG_WLAN_TWT_CONVERGED=y CONFIG_WLAN_TWT_SAP_PDEV_COUNT=y diff --git a/core/hdd/inc/wlan_hdd_tsf.h b/core/hdd/inc/wlan_hdd_tsf.h index 48d6636d7a..92012b40b0 100644 --- a/core/hdd/inc/wlan_hdd_tsf.h +++ b/core/hdd/inc/wlan_hdd_tsf.h @@ -72,6 +72,51 @@ struct hdd_tsf_op_response { uint64_t soc_time; }; +/** + * enum hdd_tsf_auto_rpt_source - trigger source of tsf auto report + * @HDD_TSF_AUTO_RPT_SOURCE_UPLINK_DELAY: uplink delay feature + * @HDD_TSF_AUTO_RPT_SOURCE_TX_LATENCY: transmit latency statistics + */ +enum hdd_tsf_auto_rpt_source { + HDD_TSF_AUTO_RPT_SOURCE_UPLINK_DELAY, + HDD_TSF_AUTO_RPT_SOURCE_TX_LATENCY, +}; + +#ifdef WLAN_FEATURE_TSF_AUTO_REPORT +/** + * hdd_set_tsf_auto_report() - enable or disable tsf auto report + * for an adapter + * @adapter: pointer to Adapter context + * @ena: requesting state (true or false) + * @source: source of the request + * + * Return: 0 for success or non-zero negative failure code + */ +int +hdd_set_tsf_auto_report(struct hdd_adapter *adapter, bool ena, + enum hdd_tsf_auto_rpt_source source); + +/** + * hdd_tsf_auto_report_init() - initialize tsf auto report related + * structures for an adapter + * @adapter: pointer to Adapter context + * + * Return: None + */ +void hdd_tsf_auto_report_init(struct hdd_adapter *adapter); +#else +static inline int +hdd_set_tsf_auto_report(struct hdd_adapter *adapter, bool ena, + enum hdd_tsf_auto_rpt_source source) +{ + return -ENOTSUPP; +} + +static inline void hdd_tsf_auto_report_init(struct hdd_adapter *adapter) +{ +} +#endif + /** * struct hdd_vdev_tsf - Adapter level tsf params * @cur_target_time: tsf value received from firmware. @@ -97,7 +142,7 @@ struct hdd_tsf_op_response { * @continuous_cap_retry_count: to store the count of continuous capture retry. * @tsf_sync_ready_flag: to indicate whether tsf_sync has been initialized. * @gpio_tsf_sync_work: work to sync send TSF CAP WMI command. - * @tsf_auto_report: to indicate if TSF auto report is enabled or not. + * @auto_rpt_src: bitmap to record trigger sources of TSF auto report */ struct hdd_vdev_tsf { uint64_t cur_target_time; @@ -130,8 +175,9 @@ struct hdd_vdev_tsf { qdf_work_t gpio_tsf_sync_work; #endif #endif /* WLAN_FEATURE_TSF_PLUS */ -#ifdef WLAN_FEATURE_TSF_UPLINK_DELAY -qdf_atomic_t tsf_auto_report; +#ifdef WLAN_FEATURE_TSF_AUTO_REPORT + unsigned long auto_rpt_src; + #endif /* WLAN_FEATURE_TSF_UPLINK_DELAY */ }; diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index a96c929fbb..2833db534b 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -4377,6 +4377,7 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, /* rcpi info initialization */ qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi)); + hdd_tsf_auto_report_init(adapter); hdd_exit(); return status; diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 11161e0637..3e04f1b725 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -7517,7 +7517,9 @@ QDF_STATUS hdd_init_station_mode(struct wlan_hdd_link_info *link_info) goto error_wmm_init; } + hdd_tsf_auto_report_init(adapter); hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); + return QDF_STATUS_SUCCESS; error_wmm_init: @@ -9682,7 +9684,6 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) WLAN_DATA_FLOW_CONTROL); hdd_reset_scan_operation(link_info); - if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { hdd_wmm_adapter_close(adapter); clear_bit(WMM_INIT_DONE, &adapter->event_flags); diff --git a/core/hdd/src/wlan_hdd_nan_datapath.c b/core/hdd/src/wlan_hdd_nan_datapath.c index 5dc22462a6..8d7a4830c4 100644 --- a/core/hdd/src/wlan_hdd_nan_datapath.c +++ b/core/hdd/src/wlan_hdd_nan_datapath.c @@ -672,6 +672,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter *adapter) hdd_set_netdev_flags(adapter); + hdd_tsf_auto_report_init(adapter); update_ndi_state(adapter, NAN_DATA_NDI_CREATING_STATE); hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID); return ret_val; diff --git a/core/hdd/src/wlan_hdd_tsf.c b/core/hdd/src/wlan_hdd_tsf.c index 95a024b94c..2bdc3af563 100644 --- a/core/hdd/src/wlan_hdd_tsf.c +++ b/core/hdd/src/wlan_hdd_tsf.c @@ -35,7 +35,7 @@ #endif #include "ol_txrx_api.h" -#ifdef WLAN_FEATURE_TSF_UPLINK_DELAY +#ifdef WLAN_FEATURE_TSF_AUTO_REPORT #include #endif @@ -3000,18 +3000,23 @@ static void wlan_hdd_phc_deinit(struct hdd_context *hdd_ctx) } #endif /* WLAN_FEATURE_TSF_PTP */ -#ifdef WLAN_FEATURE_TSF_UPLINK_DELAY -static int hdd_set_tsf_auto_report(struct hdd_adapter *adapter, bool ena) +#ifdef WLAN_FEATURE_TSF_AUTO_REPORT +void hdd_tsf_auto_report_init(struct hdd_adapter *adapter) { - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - int ret; + adapter->tsf.auto_rpt_src = 0; +} - if (QDF_IS_STATUS_ERROR(cdp_set_tsf_ul_delay_report( - soc, - adapter->deflink->vdev_id, - ena))) { - hdd_err_rl("Set tsf report uplink delay failed"); - return -EPERM; +int +hdd_set_tsf_auto_report(struct hdd_adapter *adapter, bool ena, + enum hdd_tsf_auto_rpt_source source) +{ + int ret = 0; + bool enabled; + + enabled = !!adapter->tsf.auto_rpt_src; + if (enabled == ena) { + hdd_info_rl("current %d and no action is required", enabled); + goto set_src; } ret = wma_cli_set_command((int)adapter->deflink->vdev_id, @@ -3019,67 +3024,58 @@ static int hdd_set_tsf_auto_report(struct hdd_adapter *adapter, bool ena) (int)GEN_PARAM_TSF_AUTO_REPORT_DISABLE, ena, GEN_CMD); if (ret) { - hdd_err_rl("tsf auto report %d failed", ena); - return -EINPROGRESS; + hdd_err_rl("tsf auto report %d failed: %d", ena, ret); + ret = -EINPROGRESS; + goto out; } - qdf_atomic_set(&adapter->tsf.tsf_auto_report, ena); +set_src: + if (ena) + qdf_atomic_set_bit(source, &adapter->tsf.auto_rpt_src); + else + qdf_atomic_clear_bit(source, &adapter->tsf.auto_rpt_src); - return 0; +out: + return ret; } /** - * hdd_handle_tsf_auto_report(): Handle TSF auto report enable or disable - * @adapter: pointer of struct hdd_adapter - * @tsf_cmd: TSF command from user space + * hdd_tsf_auto_report_enabled() - get current state of tsf auto report + * for an adapter + * @adapter: pointer to Adapter context * - * Return: 0 for success, -EINVAL to continue to handle other TSF commands and - * else errors + * Return: true for enabled, false for disabled */ -static int hdd_handle_tsf_auto_report(struct hdd_adapter *adapter, - uint32_t tsf_cmd) +static inline bool hdd_tsf_auto_report_enabled(struct hdd_adapter *adapter) { - bool ena; - - if (tsf_cmd != QCA_TSF_AUTO_REPORT_ENABLE && - tsf_cmd != QCA_TSF_AUTO_REPORT_DISABLE) { - hdd_debug_rl("tsf_cmd %d not for uplink delay", tsf_cmd); - return -EINVAL; - } - - /* uplink delay feature is required for STA and P2P-GC mode */ - if (adapter->device_mode != QDF_STA_MODE && - adapter->device_mode != QDF_P2P_CLIENT_MODE) { - hdd_debug_rl("tsf_cmd %d not allowed for device mode %d", - tsf_cmd, adapter->device_mode); - return -EPERM; - } - - ena = (tsf_cmd == QCA_TSF_AUTO_REPORT_ENABLE) ? true : false; - - return hdd_set_tsf_auto_report(adapter, ena); + return !!adapter->tsf.auto_rpt_src; } +/** + * hdd_set_delta_tsf() - calculate and save the time difference between + * TQM clock and TSF clock + * @adapter: pointer to Adapter context + * @ptsf: pointer to tsf information + * + * Return: QDF_STATUS + */ static QDF_STATUS hdd_set_delta_tsf(struct hdd_adapter *adapter, struct stsf *ptsf) { void *soc = cds_get_context(QDF_MODULE_ID_SOC); uint32_t delta_tsf; - /* If TSF report is for uplink delay, mac_id_valid will be set to - * 1 by target. If not, the report is not for uplink delay feature - * and return failure here so that legacy BSS TSF logic can be - * continued. + /* A tsf report event with mac_id_valid equals to 1 represents + * for tsf auto report, that's what we need to handle in this + * function; otherwise, return failure here so that legacy BSS + * TSF logic can be continued. */ if (!ptsf->mac_id_valid) { - hdd_debug_rl("TSF report not for uplink delay"); + hdd_debug_rl("Not TSF auto report"); return QDF_STATUS_E_FAILURE; } - /* For uplink delay feature, TSF auto report needs to be enabled - * first. Otherwise TSF event will not be posted by target. - */ - if (!qdf_atomic_read(&adapter->tsf.tsf_auto_report)) { + if (!hdd_tsf_auto_report_enabled(adapter)) { hdd_debug_rl("adapter %u tsf_auto_report disabled", adapter->deflink->vdev_id); goto exit_with_success; @@ -3089,7 +3085,7 @@ static QDF_STATUS hdd_set_delta_tsf(struct hdd_adapter *adapter, hdd_debug("vdev %u tsf_low %u qtimer_low %u delta_tsf %u", ptsf->vdev_id, ptsf->tsf_low, ptsf->soc_timer_low, delta_tsf); - /* Pass delta_tsf to DP layer to report uplink delay + /* Pass delta_tsf to DP layer to calculate hw delay * on a per vdev basis */ cdp_set_delta_tsf(soc, adapter->deflink->vdev_id, delta_tsf); @@ -3097,6 +3093,45 @@ static QDF_STATUS hdd_set_delta_tsf(struct hdd_adapter *adapter, exit_with_success: return QDF_STATUS_SUCCESS; } +#else /* !WLAN_FEATURE_TSF_AUTO_REPORT */ +static inline QDF_STATUS hdd_set_delta_tsf(struct hdd_adapter *adapter, + struct stsf *ptsf) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline bool hdd_tsf_auto_report_enabled(struct hdd_adapter *adapter) +{ + return false; +} +#endif /* WLAN_FEATURE_TSF_AUTO_REPORT */ + +#ifdef WLAN_FEATURE_TSF_UPLINK_DELAY +/** + * hdd_set_tsf_ul_delay_report() - enable or disable tsf uplink delay report + * for an adapter + * @adapter: pointer to Adapter context + * @ena: requesting state (true or false) + * + * Return: 0 for success or non-zero negative failure code + */ +static int +hdd_set_tsf_ul_delay_report(struct hdd_adapter *adapter, bool ena) +{ + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + QDF_STATUS status; + + status = cdp_set_tsf_ul_delay_report(soc, + adapter->deflink->vdev_id, + ena); + + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err_rl("Set tsf report uplink delay failed"); + return -EPERM; + } + + return 0; +} uint32_t hdd_get_uplink_delay_len(struct hdd_adapter *adapter) { @@ -3117,7 +3152,7 @@ QDF_STATUS hdd_add_uplink_delay(struct hdd_adapter *adapter, adapter->device_mode != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; - if (qdf_atomic_read(&adapter->tsf.tsf_auto_report)) { + if (hdd_tsf_auto_report_enabled(adapter)) { status = cdp_get_uplink_delay(soc, adapter->deflink->vdev_id, &ul_delay); if (QDF_IS_STATUS_ERROR(status)) @@ -3132,18 +3167,11 @@ QDF_STATUS hdd_add_uplink_delay(struct hdd_adapter *adapter, return QDF_STATUS_SUCCESS; } - -#else /* !WLAN_FEATURE_TSF_UPLINK_DELAY */ -static inline int hdd_handle_tsf_auto_report(struct hdd_adapter *adapter, - uint32_t tsf_cmd) +#else +static inline int +hdd_set_tsf_ul_delay_report(struct hdd_adapter *adapter, bool ena) { - return -EINVAL; -} - -static inline QDF_STATUS hdd_set_delta_tsf(struct hdd_adapter *adapter, - struct stsf *ptsf) -{ - return QDF_STATUS_E_FAILURE; + return -ENOTSUPP; } #endif /* WLAN_FEATURE_TSF_UPLINK_DELAY */ @@ -3187,7 +3215,7 @@ int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf) } adapter = link_info->adapter; - /* Intercept tsf report and check if it is for uplink delay. + /* Intercept tsf report and check if it is for auto report. * If yes, return in advance and skip the legacy BSS TSF * report. Otherwise continue on to the legacy BSS TSF * report logic. @@ -3268,6 +3296,9 @@ static int __wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy, uint32_t tsf_cmd; enum qca_nl80211_vendor_subcmds_index index = QCA_NL80211_VENDOR_SUBCMD_TSF_INDEX; + bool enable_auto_rpt; + enum hdd_tsf_auto_rpt_source source = + HDD_TSF_AUTO_RPT_SOURCE_UPLINK_DELAY; hdd_enter_dev(wdev->netdev); @@ -3292,13 +3323,22 @@ static int __wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy, } tsf_cmd = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TSF_CMD]); - /* Intercept tsf_cmd for TSF auto report enable or disable subcmds. - * If status is -EINVAL, it means tsf_cmd is not for auto report and - * need to continue to handle other tsf cmds. + /* Intercept tsf_cmd for TSF auto report enable or disable subcmds, + * and treat as trigger for uplink delay report. */ - status = hdd_handle_tsf_auto_report(adapter, tsf_cmd); - if (status != -EINVAL) + if (tsf_cmd == QCA_TSF_AUTO_REPORT_DISABLE || + tsf_cmd == QCA_TSF_AUTO_REPORT_ENABLE) { + enable_auto_rpt = (tsf_cmd == QCA_TSF_AUTO_REPORT_ENABLE); + status = hdd_set_tsf_auto_report(adapter, + enable_auto_rpt, + source); + if (status) + goto end; + + hdd_set_tsf_ul_delay_report(adapter, enable_auto_rpt); goto end; + } + ret = qdf_event_reset(&tsf_sync_get_completion_evt); if (QDF_IS_STATUS_ERROR(ret)) hdd_warn("failed to reset tsf_sync_get_completion_evt"); diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index c5cca0a409..564c502426 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1245,7 +1245,7 @@ QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id); QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id); QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin); -#ifdef WLAN_FEATURE_TSF_UPLINK_DELAY +#ifdef WLAN_FEATURE_TSF_AUTO_REPORT /** * wma_set_tsf_auto_report() - Set TSF auto report in firmware * @wma_handle: wma handle @@ -1257,14 +1257,14 @@ QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin); */ QDF_STATUS wma_set_tsf_auto_report(WMA_HANDLE handle, uint32_t vdev_id, uint32_t param_id, bool ena); -#else /* !WLAN_FEATURE_TSF_UPLINK_DELAY */ +#else /* !WLAN_FEATURE_TSF_AUTO_REPORT */ static inline QDF_STATUS wma_set_tsf_auto_report(WMA_HANDLE handle, uint32_t vdev_id, uint32_t param_id, bool ena) { - return QDF_STATUS_E_FAILURE; + return QDF_STATUS_E_NOSUPPORT; } -#endif /* WLAN_FEATURE_TSF_UPLINK_DELAY */ +#endif /* WLAN_FEATURE_TSF_AUTO_REPORT */ #else static inline QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 7d4d722c90..3de4e0ce8a 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -318,7 +318,7 @@ end: #ifdef WLAN_FEATURE_TSF -#if defined(WLAN_FEATURE_TSF_UPLINK_DELAY) || defined(QCA_GET_TSF_VIA_REG) +#if defined(WLAN_FEATURE_TSF_AUTO_REPORT) || defined(QCA_GET_TSF_VIA_REG) static inline void wma_vdev_tsf_set_mac_id_tsf_id(struct stsf *ptsf, uint32_t mac_id, uint32_t mac_id_valid, uint32_t tsf_id, @@ -333,14 +333,14 @@ wma_vdev_tsf_set_mac_id_tsf_id(struct stsf *ptsf, uint32_t mac_id, ptsf->mac_id, ptsf->mac_id_valid, ptsf->tsf_id, ptsf->tsf_id_valid); } -#else /* !WLAN_FEATURE_TSF_UPLINK_DELAY || !QCA_GET_TSF_VIA_REG*/ +#else /* !(WLAN_FEATURE_TSF_AUTO_REPORT || QCA_GET_TSF_VIA_REG) */ static inline void wma_vdev_tsf_set_mac_id_tsf_id(struct stsf *ptsf, uint32_t mac_id, uint32_t mac_id_valid, uint32_t tsf_id, uint32_t tsf_id_valid) { } -#endif /* WLAN_FEATURE_TSF_UPLINK_DELAY || QCA_GET_TSF_VIA_REG*/ +#endif /* WLAN_FEATURE_TSF_AUTO_REPORT || QCA_GET_TSF_VIA_REG */ /** * wma_vdev_tsf_handler() - handle tsf event indicated by FW @@ -515,7 +515,7 @@ QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin) return QDF_STATUS_SUCCESS; } -#ifdef WLAN_FEATURE_TSF_UPLINK_DELAY +#ifdef WLAN_FEATURE_TSF_AUTO_REPORT QDF_STATUS wma_set_tsf_auto_report(WMA_HANDLE handle, uint32_t vdev_id, uint32_t param_id, bool ena) { @@ -560,7 +560,7 @@ QDF_STATUS wma_set_tsf_auto_report(WMA_HANDLE handle, uint32_t vdev_id, return status; } -#endif /* WLAN_FEATURE_TSF_UPLINK_DELAY */ +#endif /* WLAN_FEATURE_TSF_AUTO_REPORT */ #endif /**