diff --git a/Kbuild b/Kbuild index 4ca8f1d63e4e..2ea9998d9089 100644 --- a/Kbuild +++ b/Kbuild @@ -2209,9 +2209,11 @@ cppflags-$(CONFIG_ATH_PCIE_ACCESS_DEBUG) += -DCONFIG_ATH_PCIE_ACCESS_DEBUG # Enable feature support for Linux version QCMBR cppflags-$(CONFIG_LINUX_QCMBR) += -DLINUX_QCMBR -# Enable featue sync tsf between multi devices +# Enable feature sync tsf between multi devices cppflags-$(CONFIG_WLAN_SYNC_TSF) += -DWLAN_FEATURE_TSF cppflags-$(CONFIG_WLAN_SYNC_TSF_PLUS) += -DWLAN_FEATURE_TSF_PLUS +# Enable feature sync tsf for chips based on Adrastea arch +cppflags-$(CONFIG_WLAN_SYNC_TSF_PLUS_NOIRQ) += -DWLAN_FEATURE_TSF_PLUS_NOIRQ cppflags-$(CONFIG_ATH_PROCFS_DIAG_SUPPORT) += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT diff --git a/configs/default_defconfig b/configs/default_defconfig index aea5dd800fa1..87793ee6e559 100644 --- a/configs/default_defconfig +++ b/configs/default_defconfig @@ -80,6 +80,11 @@ ifeq ($(CONFIG_ARCH_MSM8917), y) endif endif +ifeq ($(CONFIG_ARCH_QCS405), y) + CONFIG_WLAN_SYNC_TSF_PLUS := y + CONFIG_WLAN_SYNC_TSF_PLUS_NOIRQ := y +endif + #Flag to enable Legacy Fast Roaming2(LFR2) CONFIG_QCACLD_WLAN_LFR2 := y #Flag to enable Legacy Fast Roaming3(LFR3) diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 3222cc9fabaf..5fcfb9f89b5b 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -2234,7 +2234,7 @@ bool cds_is_ptp_rx_opt_enabled(void) return false; } - return HDD_TSF_IS_RX_SET(hdd_ctx); + return hdd_tsf_is_rx_set(hdd_ctx); } bool cds_is_ptp_tx_opt_enabled(void) @@ -2254,7 +2254,7 @@ bool cds_is_ptp_tx_opt_enabled(void) return false; } - return HDD_TSF_IS_TX_SET(hdd_ctx); + return hdd_tsf_is_tx_set(hdd_ctx); } #endif diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index af03161f6c43..59b81a730d0b 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1359,6 +1359,7 @@ struct hdd_adapter { /* tsf value received from firmware */ uint64_t cur_target_time; uint64_t tsf_sync_soc_timer; + qdf_mc_timer_t host_capture_req_timer; #ifdef WLAN_FEATURE_TSF_PLUS /* spin lock for read/write timestamps */ qdf_spinlock_t host_target_sync_lock; diff --git a/core/hdd/inc/wlan_hdd_tsf.h b/core/hdd/inc/wlan_hdd_tsf.h index 91b679ad9248..81235ecb09bc 100644 --- a/core/hdd/inc/wlan_hdd_tsf.h +++ b/core/hdd/inc/wlan_hdd_tsf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -19,8 +19,7 @@ #if !defined WLAN_HDD_TSF_H #define WLAN_HDD_TSF_H #include "wlan_hdd_cfg.h" - -struct hdd_context; +#include "wlan_hdd_main.h" /** * enum hdd_tsf_get_state - status of get tsf action @@ -125,6 +124,7 @@ int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy, int data_len); int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf); + #else static inline void wlan_hdd_tsf_init(struct hdd_context *hdd_ctx) { @@ -161,39 +161,52 @@ static inline int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf) #endif #if defined(WLAN_FEATURE_TSF_PLUS) && defined(WLAN_FEATURE_TSF) -#define HDD_TSF_IS_PTP_ENABLED(hdd) \ -({ \ - struct hdd_context *hdd_ctx = (hdd); \ - hdd_ctx && hdd_ctx->config && hdd_ctx->config->tsf_ptp_options; \ -}) +/** + * hdd_tsf_is_ptp_enabled() - check ini configuration + * @hdd: pointer to hdd context + * + * This function checks tsf configuration for ptp + * + * Return: true on enable, false on disable + */ +bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd); +/** + * hdd_tsf_is_tx_set() - check ini configuration + * @hdd: pointer to hdd context + * + * This function checks tsf configuration for ptp on tx + * + * Return: true on enable, false on disable + */ -#define HDD_TSF_IS_TX_SET(hdd) \ -({ \ - struct hdd_context *hdd_ctx = (hdd); \ - hdd_ctx && hdd_ctx->config && \ - (hdd_ctx->config->tsf_ptp_options & CFG_SET_TSF_PTP_OPT_TX); \ -}) - -#define HDD_TSF_IS_RX_SET(hdd) \ -({ \ - struct hdd_context *hdd_ctx = (hdd); \ - hdd_ctx && hdd_ctx->config && \ - (hdd_ctx->config->tsf_ptp_options & CFG_SET_TSF_PTP_OPT_RX); \ -}) - -#define HDD_TSF_IS_RAW_SET(hdd) \ -({ \ - struct hdd_context *hdd_ctx = (hdd); \ - hdd_ctx && hdd_ctx->config && \ - (hdd_ctx->config->tsf_ptp_options & CFG_SET_TSF_PTP_OPT_RAW); \ -}) - -#define HDD_TSF_IS_DBG_FS_SET(hdd) \ -({ \ - struct hdd_context *hdd_ctx = (hdd); \ - hdd_ctx && hdd_ctx->config && \ - (hdd_ctx->config->tsf_ptp_options & CFG_SET_TSF_DBG_FS); \ -}) +bool hdd_tsf_is_tx_set(struct hdd_context *hdd); +/** + * hdd_tsf_is_rx_set() - check ini configuration + * @hdd: pointer to hdd context + * + * This function checks tsf configuration for ptp on rx + * + * Return: true on enable, false on disable + */ +bool hdd_tsf_is_rx_set(struct hdd_context *hdd); +/** + * hdd_tsf_is_raw_set() - check ini configuration + * @hdd: pointer to hdd context + * + * This function checks tsf configuration for ptp on raw + * + * Return: true on enable, false on disable + */ +bool hdd_tsf_is_raw_set(struct hdd_context *hdd); +/** + * hdd_tsf_is_dbg_fs_set() - check ini configuration + * @hdd: pointer to hdd context + * + * This function checks tsf configuration for ptp on dbg fs + * + * Return: true on enable, false on disable + */ +bool hdd_tsf_is_dbg_fs_set(struct hdd_context *hdd); /** * hdd_start_tsf_sync() - start tsf sync @@ -255,6 +268,17 @@ int hdd_tx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time); * Return: Describe the execute result of this routine */ int hdd_rx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time); +/** + * hdd_capture_req_timer_expired_handler() - capture req timer handler + * @arg: pointer to a adapter + * + * This function set a timeout handler for TSF capture timer. + * + * Return: none + */ + +void hdd_capture_req_timer_expired_handler(void *arg); + #else static inline int hdd_start_tsf_sync(struct hdd_adapter *adapter) { @@ -285,6 +309,11 @@ int hdd_rx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time) { return -ENOTSUPP; } + +static inline +void hdd_capture_req_timer_expired_handler(void *arg) +{ +} #endif #endif diff --git a/core/hdd/src/wlan_hdd_tsf.c b/core/hdd/src/wlan_hdd_tsf.c index c184a1c7f486..2ed913682ade 100644 --- a/core/hdd/src/wlan_hdd_tsf.c +++ b/core/hdd/src/wlan_hdd_tsf.c @@ -25,9 +25,13 @@ #include "wma_api.h" #include "wlan_fwol_ucfg_api.h" #include - +#include +#include "ol_txrx_api.h" static struct completion tsf_sync_get_completion_evt; #define WLAN_TSF_SYNC_GET_TIMEOUT 2000 +#define WLAN_HDD_CAPTURE_TSF_REQ_TIMEOUT_MS 500 +#define WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS 100 + /** * enum hdd_tsf_op_result - result of tsf operation * @@ -40,6 +44,8 @@ enum hdd_tsf_op_result { }; #ifdef WLAN_FEATURE_TSF_PLUS +#define WLAN_HDD_CAPTURE_TSF_RESYNC_INTERVAL 9 + static inline void hdd_set_th_sync_status(struct hdd_adapter *adapter, bool initialized) { @@ -116,12 +122,61 @@ static bool hdd_tsf_is_initialized(struct hdd_adapter *adapter) * * Return: TSF_RETURN on Success, TSF_RESET_GPIO_FAIL on failure */ -#ifdef QCA_WIFI_3_0 +#if defined(WLAN_FEATURE_TSF_PLUS_NOIRQ) && defined(WLAN_FEATURE_TSF_PLUS) static int hdd_tsf_reset_gpio(struct hdd_adapter *adapter) { /* No GPIO Host timer sync for integrated WIFI Device */ return TSF_RETURN; } + +/** + * hdd_tsf_set_gpio() - Set TSF GPIO used for host timer sync + * @hdd_ctx: pointer to hdd context + * + * This function is a dummy function for adrastea arch + * + * Return: QDF_STATUS_SUCCESS on Success + */ + +static QDF_STATUS hdd_tsf_set_gpio(struct hdd_context *hdd_ctx) +{ + return QDF_STATUS_SUCCESS; +} + +bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd) +{ + return (hdd && (hdd->config) && + (hdd->config->tsf_ptp_options)); +} + +bool hdd_tsf_is_tx_set(struct hdd_context *hdd) +{ + return (hdd && (hdd->config) && + ((hdd->config->tsf_ptp_options) + & CFG_SET_TSF_PTP_OPT_TX)); +} + +bool hdd_tsf_is_rx_set(struct hdd_context *hdd) +{ + return (hdd && (hdd->config) && + ((hdd->config->tsf_ptp_options) + & CFG_SET_TSF_PTP_OPT_RX)); +} + +bool hdd_tsf_is_raw_set(struct hdd_context *hdd) +{ + return (hdd && (hdd->config) && + ((hdd->config->tsf_ptp_options) + & CFG_SET_TSF_PTP_OPT_RAW)); +} + +bool hdd_tsf_is_dbg_fs_set(struct hdd_context *hdd) +{ + return (hdd && (hdd->config) && + ((hdd->config->tsf_ptp_options) + & CFG_SET_TSF_DBG_FS)); +} + #else static int hdd_tsf_reset_gpio(struct hdd_adapter *adapter) { @@ -139,6 +194,33 @@ static int hdd_tsf_reset_gpio(struct hdd_adapter *adapter) } return ret; } + +/** + * hdd_tsf_set_gpio() - Set TSF GPIO used for host timer sync + * @hdd_ctx: pointer to hdd context + * + * This function check GPIO and set GPIO as IRQ to FW side on + * none Adrastea arch + * + * Return: QDF_STATUS_SUCCESS on Success, others on Failure. + */ +static QDF_STATUS hdd_tsf_set_gpio(struct hdd_context *hdd_ctx) +{ + QDF_STATUS status; + uint32_t tsf_gpio_pin = TSF_GPIO_PIN_INVALID; + + status = ucfg_fwol_get_tsf_gpio_pin(hdd_ctx->psoc, &tsf_gpio_pin); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_INVAL; + + if (tsf_gpio_pin == TSF_GPIO_PIN_INVALID) + return QDF_STATUS_E_INVAL; + + status = sme_set_tsf_gpio(hdd_ctx->mac_handle, + tsf_gpio_pin); + + return status; +} #endif static enum hdd_tsf_op_result hdd_capture_tsf_internal( @@ -146,6 +228,7 @@ static enum hdd_tsf_op_result hdd_capture_tsf_internal( { int ret; struct hdd_context *hddctx; + qdf_mc_timer_t *cap_timer; if (adapter == NULL || buf == NULL) { hdd_err("invalid pointer"); @@ -179,7 +262,12 @@ static enum hdd_tsf_op_result hdd_capture_tsf_internal( /* record adapter for cap_tsf_irq_handler */ hddctx->cap_tsf_context = adapter; - hdd_err("+ioctl issue cap tsf cmd"); + hdd_info("+ioctl issue cap tsf cmd"); + cap_timer = &adapter->host_capture_req_timer; + qdf_mc_timer_init(cap_timer, QDF_TIMER_TYPE_SW, + hdd_capture_req_timer_expired_handler, + (void *)adapter); + qdf_mc_timer_start(cap_timer, WLAN_HDD_CAPTURE_TSF_REQ_TIMEOUT_MS); /* Reset TSF value for new capture */ adapter->cur_target_time = 0; @@ -194,9 +282,12 @@ static enum hdd_tsf_op_result hdd_capture_tsf_internal( buf[0] = TSF_CAPTURE_FAIL; hddctx->cap_tsf_context = NULL; qdf_atomic_set(&hddctx->cap_tsf_flag, 0); + qdf_mc_timer_stop(&adapter->host_capture_req_timer); + qdf_mc_timer_destroy(&adapter->host_capture_req_timer); + return HDD_TSF_OP_SUCC; } - hdd_err("-ioctl return cap tsf cmd"); + hdd_info("-ioctl return cap tsf cmd"); return HDD_TSF_OP_SUCC; } @@ -273,7 +364,6 @@ static enum hdd_tsf_op_result hdd_indicate_tsf_internal( * equal or less than (1/2 * OVERFLOW_INDICATOR32 us) */ #define WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC 10 -#define WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS 100 #define OVERFLOW_INDICATOR32 (((int64_t)0x1) << 32) #define CAP_TSF_TIMER_FIX_SEC 1 @@ -397,7 +487,7 @@ enum hdd_ts_status hdd_check_timestamp_status( /* the deviation should be smaller than a threshold */ if (delta_ns > MAX_ALLOWED_DEVIATION_NS) { - hdd_info("Invalid timestamps - delta: %llu ns", delta_ns); + hdd_warn("Invalid timestamps - delta: %llu ns", delta_ns); return HDD_TS_STATUS_INVALID; } return HDD_TS_STATUS_READY; @@ -420,8 +510,15 @@ static void hdd_update_timestamp(struct hdd_adapter *adapter, * avoid requiring spin lock, and to speed up the IRQ processing. */ if (host_time > 0) { + /* on ADREASTEA ach, Qtime is used to sync host and tsf time as a + * intermedia there is no IRQ to sync up TSF-HOST, so host time in ns + * and target in us will be updated at the same time in WMI command + * callback + */ adapter->cur_host_time = host_time; - return; + + if (0 == target_time) + return; } qdf_spin_lock_bh(&adapter->host_target_sync_lock); @@ -432,17 +529,20 @@ static void hdd_update_timestamp(struct hdd_adapter *adapter, adapter->last_host_time, adapter->cur_target_time, adapter->cur_host_time); + hdd_info("sync_status %d", sync_status); switch (sync_status) { case HDD_TS_STATUS_INVALID: if (++adapter->continuous_error_count < MAX_CONTINUOUS_ERROR_CNT) { interval = WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS; + adapter->last_target_time = adapter->cur_target_time; + adapter->last_host_time = adapter->cur_host_time; adapter->cur_target_time = 0; adapter->cur_host_time = 0; break; } - hdd_info("Reach the max continuous error count"); + hdd_warn("Reach the max continuous error count"); /* * fall through: * If reach MAX_CONTINUOUS_ERROR_CNT, treat it as a @@ -472,9 +572,12 @@ static void hdd_update_timestamp(struct hdd_adapter *adapter, interval = (WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC - CAP_TSF_TIMER_FIX_SEC) * MSEC_PER_SEC; adapter->continuous_error_count = 0; + hdd_debug("ts-pair updated: interval: %d", + interval); break; case HDD_TS_STATUS_WAITING: interval = 0; + hdd_warn("TS status is waiting due to one or more pair not updated"); break; } qdf_spin_unlock_bh(&adapter->host_target_sync_lock); @@ -614,7 +717,7 @@ static inline int32_t hdd_get_targettime_from_hosttime( static inline uint64_t hdd_get_monotonic_host_time(struct hdd_context *hdd_ctx) { - return HDD_TSF_IS_RAW_SET(hdd_ctx) ? + return hdd_tsf_is_raw_set(hdd_ctx) ? ktime_get_ns() : ktime_get_real_ns(); } @@ -646,6 +749,7 @@ static ssize_t __hdd_wlan_tsf_show(struct device *dev, return scnprintf(buf, PAGE_SIZE, "Invalid HDD context\n"); host_time = hdd_get_monotonic_host_time(hdd_ctx); + if (hdd_get_targettime_from_hosttime(adapter, host_time, &target_time)) size = scnprintf(buf, PAGE_SIZE, "Invalid timestamp\n"); @@ -653,6 +757,7 @@ static ssize_t __hdd_wlan_tsf_show(struct device *dev, size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n", buf, target_time, host_time, hdd_sta_ctx->conn_info.bssId.bytes); + return size; } @@ -682,6 +787,7 @@ static void hdd_capture_tsf_timer_expired_handler(void *arg) hdd_capture_tsf_internal(adapter, &tsf_op_resp, 1); } +#ifndef WLAN_FEATURE_TSF_PLUS_NOIRQ static irqreturn_t hdd_tsf_captured_irq_handler(int irq, void *arg) { struct hdd_adapter *adapter; @@ -713,6 +819,58 @@ static irqreturn_t hdd_tsf_captured_irq_handler(int irq, void *arg) return IRQ_HANDLED; } +#endif + +void hdd_capture_req_timer_expired_handler(void *arg) +{ + struct hdd_adapter *adapter; + struct hdd_context *hdd_ctx; + QDF_TIMER_STATE capture_req_timer_status; + qdf_mc_timer_t *sync_timer; + int interval; + int ret; + + if (!arg) + return; + adapter = (struct hdd_adapter *)arg; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (!hdd_ctx) { + hdd_warn("invalid hdd context"); + return; + } + + if (!hdd_tsf_is_initialized(adapter)) { + qdf_mc_timer_destroy(&adapter->host_capture_req_timer); + hdd_warn("tsf not init"); + return; + } + + qdf_spin_lock_bh(&adapter->host_target_sync_lock); + adapter->cur_host_time = 0; + adapter->cur_target_time = 0; + qdf_spin_unlock_bh(&adapter->host_target_sync_lock); + + ret = hdd_tsf_reset_gpio(adapter); + if (0 != ret) + hdd_info("reset tsf gpio fail"); + + hdd_ctx->cap_tsf_context = NULL; + qdf_atomic_set(&hdd_ctx->cap_tsf_flag, 0); + qdf_mc_timer_destroy(&adapter->host_capture_req_timer); + + sync_timer = &adapter->host_target_sync_timer; + capture_req_timer_status = + qdf_mc_timer_get_current_state(sync_timer); + + if (capture_req_timer_status == QDF_TIMER_STATE_UNUSED) { + hdd_warn("invalid timer status"); + return; + } + + interval = WLAN_HDD_CAPTURE_TSF_RESYNC_INTERVAL * MSEC_PER_SEC; + qdf_mc_timer_start(sync_timer, interval); +} static enum hdd_tsf_op_result hdd_tsf_sync_init(struct hdd_adapter *adapter) { @@ -753,7 +911,7 @@ static enum hdd_tsf_op_result hdd_tsf_sync_init(struct hdd_adapter *adapter) } net_dev = adapter->dev; - if (net_dev && HDD_TSF_IS_DBG_FS_SET(hddctx)) + if (net_dev && hdd_tsf_is_dbg_fs_set(hddctx)) device_create_file(&net_dev->dev, &dev_attr_tsf); hdd_set_th_sync_status(adapter, true); @@ -778,7 +936,6 @@ static enum hdd_tsf_op_result hdd_tsf_sync_deinit(struct hdd_adapter *adapter) } hdd_set_th_sync_status(adapter, false); - ret = qdf_mc_timer_destroy(&adapter->host_target_sync_timer); if (ret != QDF_STATUS_SUCCESS) hdd_err("Failed to destroy timer, ret: %d", ret); @@ -800,7 +957,7 @@ static enum hdd_tsf_op_result hdd_tsf_sync_deinit(struct hdd_adapter *adapter) hdd_reset_timestamps(adapter); net_dev = adapter->dev; - if (net_dev && HDD_TSF_IS_DBG_FS_SET(hddctx)) { + if (net_dev && hdd_tsf_is_dbg_fs_set(hddctx)) { struct device *dev = &net_dev->dev; device_remove_file(dev, &dev_attr_tsf); @@ -808,6 +965,22 @@ static enum hdd_tsf_op_result hdd_tsf_sync_deinit(struct hdd_adapter *adapter) return HDD_TSF_OP_SUCC; } +#ifdef WLAN_FEATURE_TSF_PLUS_NOIRQ +static inline void hdd_update_tsf(struct hdd_adapter *adapter, uint64_t tsf) +{ + uint32_t tsf_op_resp[3]; + struct hdd_context *hddctx; + uint64_t host_time; + + hddctx = WLAN_HDD_GET_CTX(adapter); + host_time = hdd_get_monotonic_host_time(hddctx); + hdd_indicate_tsf_internal(adapter, tsf_op_resp, 3); + host_time -= qdf_log_timestamp_to_usecs(qdf_get_log_timestamp() + - adapter->tsf_sync_soc_timer) * NSEC_PER_USEC; + adapter->cur_host_time = host_time; + hdd_update_timestamp(adapter, tsf, host_time); +} +#else static inline void hdd_update_tsf(struct hdd_adapter *adapter, uint64_t tsf) { uint32_t tsf_op_resp[3]; @@ -815,6 +988,7 @@ static inline void hdd_update_tsf(struct hdd_adapter *adapter, uint64_t tsf) hdd_indicate_tsf_internal(adapter, tsf_op_resp, 3); hdd_update_timestamp(adapter, tsf, 0); } +#endif static inline enum hdd_tsf_op_result hdd_netbuf_timestamp(qdf_nbuf_t netbuf, @@ -959,12 +1133,65 @@ static inline int __hdd_indicate_tsf(struct hdd_adapter *adapter, return 0; } +#ifdef WLAN_FEATURE_TSF_PLUS_NOIRQ +static inline +enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx) +{ + if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) { + hdd_info("To enable TSF_PLUS, set gtsf_ptp_options in ini"); + return HDD_TSF_OP_FAIL; + } + + if (hdd_tsf_is_tx_set(hdd_ctx)) + ol_register_timestamp_callback(hdd_tx_timestamp); + return HDD_TSF_OP_SUCC; +} + +static inline +enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) +{ + QDF_STATUS status; + QDF_TIMER_STATE capture_req_timer_status; + qdf_mc_timer_t *cap_timer; + struct hdd_adapter *adapter, *adapternode_ptr, *next_ptr; + + if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) + return HDD_TSF_OP_SUCC; + + if (hdd_tsf_is_tx_set(hdd_ctx)) + ol_deregister_timestamp_callback(); + + status = hdd_get_front_adapter(hdd_ctx, &adapternode_ptr); + + while (NULL != adapternode_ptr && QDF_STATUS_SUCCESS == status) { + adapter = adapternode_ptr; + status = + hdd_get_next_adapter(hdd_ctx, adapternode_ptr, &next_ptr); + adapternode_ptr = next_ptr; + if (adapter->host_capture_req_timer.state == 0) + continue; + cap_timer = &adapter->host_capture_req_timer; + capture_req_timer_status = + qdf_mc_timer_get_current_state(cap_timer); + + if (capture_req_timer_status != QDF_TIMER_STATE_UNUSED) { + qdf_mc_timer_stop(cap_timer); + status = + qdf_mc_timer_destroy(cap_timer); + if (status != QDF_STATUS_SUCCESS) + hdd_err("remove timer failed: %d", status); + } + } + + return HDD_TSF_OP_SUCC; +} +#else static inline enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx) { int ret; - if (!HDD_TSF_IS_PTP_ENABLED(hdd_ctx)) { + if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) { hdd_info("To enable TSF_PLUS, set gtsf_ptp_options in ini"); return HDD_TSF_OP_FAIL; } @@ -978,7 +1205,7 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx) return HDD_TSF_OP_FAIL; } - if (HDD_TSF_IS_TX_SET(hdd_ctx)) + if (hdd_tsf_is_tx_set(hdd_ctx)) ol_register_timestamp_callback(hdd_tx_timestamp); return HDD_TSF_OP_SUCC; } @@ -988,10 +1215,10 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) { int ret; - if (!HDD_TSF_IS_PTP_ENABLED(hdd_ctx)) + if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) return HDD_TSF_OP_SUCC; - if (HDD_TSF_IS_TX_SET(hdd_ctx)) + if (hdd_tsf_is_tx_set(hdd_ctx)) ol_deregister_timestamp_callback(); ret = cnss_common_unregister_tsf_captured_handler( @@ -1005,6 +1232,7 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) return HDD_TSF_OP_SUCC; } +#endif void hdd_tsf_notify_wlan_state_change(struct hdd_adapter *adapter, eConnectionState old_state, @@ -1078,7 +1306,10 @@ int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf) { struct hdd_context *hddctx; struct hdd_adapter *adapter; - int status; + int ret; + QDF_STATUS status; + QDF_TIMER_STATE capture_req_timer_status; + qdf_mc_timer_t *capture_timer; if (pcb_cxt == NULL || ptsf == NULL) { hdd_err("HDD context is not valid"); @@ -1086,8 +1317,8 @@ int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf) } hddctx = (struct hdd_context *)pcb_cxt; - status = wlan_hdd_validate_context(hddctx); - if (0 != status) + ret = wlan_hdd_validate_context(hddctx); + if (0 != ret) return -EINVAL; adapter = hdd_get_adapter_by_vdev(hddctx, ptsf->vdev_id); @@ -1105,6 +1336,19 @@ int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf) hdd_info("tsf cb handle event, device_mode is %d", adapter->device_mode); + capture_timer = &adapter->host_capture_req_timer; + capture_req_timer_status = + qdf_mc_timer_get_current_state(capture_timer); + if (capture_req_timer_status == QDF_TIMER_STATE_UNUSED) { + hdd_warn("invalid timer status"); + return -EINVAL; + } + + qdf_mc_timer_stop(capture_timer); + status = qdf_mc_timer_destroy(capture_timer); + if (status != QDF_STATUS_SUCCESS) + hdd_warn("destroy cap req timer fail, ret: %d", status); + adapter->cur_target_time = ((uint64_t)ptsf->tsf_high << 32 | ptsf->tsf_low); adapter->tsf_sync_soc_timer = ((uint64_t) ptsf->soc_timer_high << 32 | @@ -1239,7 +1483,7 @@ static int __wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy, } end: - hdd_info("TSF operation %d Status: %d", tsf_cmd, status); + hdd_info("TSF operation %d status: %d", tsf_cmd, status); return status; } @@ -1269,7 +1513,6 @@ int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy, void wlan_hdd_tsf_init(struct hdd_context *hdd_ctx) { QDF_STATUS status; - uint32_t tsf_gpio_pin = TSF_GPIO_PIN_INVALID; if (!hdd_ctx) return; @@ -1279,15 +1522,8 @@ void wlan_hdd_tsf_init(struct hdd_context *hdd_ctx) qdf_atomic_init(&hdd_ctx->cap_tsf_flag); - status = ucfg_fwol_get_tsf_gpio_pin(hdd_ctx->psoc, &tsf_gpio_pin); - if (QDF_IS_STATUS_ERROR(status)) - return; + status = hdd_tsf_set_gpio(hdd_ctx); - if (tsf_gpio_pin == TSF_GPIO_PIN_INVALID) - goto fail; - - status = sme_set_tsf_gpio(hdd_ctx->mac_handle, - tsf_gpio_pin); if (QDF_STATUS_SUCCESS != status) { hdd_err("set tsf GPIO failed, status: %d", status); goto fail; diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index b3466f08bbfb..bd41eda87849 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -1810,7 +1810,7 @@ static inline void hdd_tsf_timestamp_rx(struct hdd_context *hdd_ctx, qdf_nbuf_t netbuf, uint64_t target_time) { - if (!HDD_TSF_IS_RX_SET(hdd_ctx)) + if (!hdd_tsf_is_rx_set(hdd_ctx)) return; hdd_rx_timestamp(netbuf, target_time); diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index de3e57bd4de9..9943b226065f 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1507,13 +1507,8 @@ QDF_STATUS sme_set_tsfcb(tHalHandle hHal, QDF_STATUS sme_reset_tsfcb(tHalHandle h_hal); -#ifdef WLAN_FEATURE_TSF +#if defined(WLAN_FEATURE_TSF) && !defined(WLAN_FEATURE_TSF_PLUS_NOIRQ) QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue); -#else -static inline QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue) -{ - return QDF_STATUS_E_FAILURE; -} #endif QDF_STATUS sme_update_mimo_power_save(tHalHandle hHal, diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 182f6e4978a4..53898ac77a86 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -5499,9 +5499,9 @@ QDF_STATUS sme_reset_tsfcb(tHalHandle h_hal) return status; } -#ifdef WLAN_FEATURE_TSF +#if defined(WLAN_FEATURE_TSF) && !defined(WLAN_FEATURE_TSF_PLUS_NOIRQ) /* - * sme_set_tsf_gpio() - set gpio pin that be toggled when capture tef + * sme_set_tsf_gpio() - set gpio pin that be toggled when capture tsf * @h_hal: Handler return by mac_open * @pinvalue: gpio pin id *