diff options
| author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-04-25 21:16:17 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-04-25 21:16:17 -0700 |
| commit | ab829079c8edba8d0929c9bd8db93ca1ee929a4e (patch) | |
| tree | 73b51adc19d3ec29ae3a0369d88b7263adbeded4 | |
| parent | 0f4e5eaccdade6a811cd3664aa8e6119fbe066d2 (diff) | |
| parent | 7e9fd6e65efa6c334cfe57f365f4037cf8501c53 (diff) | |
Merge "qcacld-2.0: add support for target-host synchronization" into wlan-cld2.driver.lnx.1.0-dev
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_main.h | 13 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_tsf.h | 59 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_wext.h | 4 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_assoc.c | 5 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_tsf.c | 540 | ||||
| -rw-r--r-- | Kbuild | 14 |
6 files changed, 628 insertions, 7 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index e02bca29de64..0425476ac21e 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -1338,6 +1338,19 @@ struct hdd_adapter_s #ifdef WLAN_FEATURE_TSF /* tsf value get from firmware */ uint64_t cur_target_time; + +#ifdef WLAN_FEATURE_TSF_PLUS + /* spin lock for read/write timestamps */ + spinlock_t host_target_sync_lock; + vos_timer_t host_target_sync_timer; + uint64_t cur_host_time; + uint64_t last_host_time; + uint64_t last_target_time; + /* to store the count of continuous invalid tstamp-pair */ + int continuous_error_count; + /* to indicate whether tsf_sync has been initialized */ + adf_os_atomic_t tsf_sync_ready_flag; +#endif /* WLAN_FEATURE_TSF_PLUS */ #endif hdd_cfg80211_state_t cfg80211State; diff --git a/CORE/HDD/inc/wlan_hdd_tsf.h b/CORE/HDD/inc/wlan_hdd_tsf.h index d9ba92cc9662..42d512983466 100644 --- a/CORE/HDD/inc/wlan_hdd_tsf.h +++ b/CORE/HDD/inc/wlan_hdd_tsf.h @@ -69,7 +69,6 @@ void wlan_hdd_tsf_deinit(hdd_context_t *hdd_ctx); /** * hdd_capture_tsf() - capture tsf - * * @adapter: pointer to adapter * @buf: pointer to uplayer buf * @len : the length of buf @@ -82,7 +81,6 @@ int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len); /** * hdd_indicate_tsf() - return tsf to uplayer - * * @adapter: pointer to adapter * @buf: pointer to uplayer buf * @len : the length of buf @@ -115,4 +113,61 @@ hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) } #endif +#if defined(WLAN_FEATURE_TSF_PLUS) && defined(WLAN_FEATURE_TSF) + +/** + * hdd_start_tsf_sync() - start tsf sync + * @adapter: pointer to adapter + * + * This function initialize and start TSF synchronization + * + * Return: Describe the execute result of this routine + */ +int hdd_start_tsf_sync(hdd_adapter_t *adapter); + +/** + * hdd_stop_tsf_sync() - stop tsf sync + * @adapter: pointer to adapter + * + * This function stop and de-initialize TSF synchronization + * + * Return: Describe the execute result of this routine + */ +int hdd_stop_tsf_sync(hdd_adapter_t *adapter); + +/** + * hdd_tsf_notify_wlan_state_change() - + * notify tsf module of wlan connection state + * @old_state: old wlan state + * @new_state: new wlan state + * + * This function check the old and new connection state, determine whether + * to start or stop tsf sync + * + * Return: nothing + */ +void hdd_tsf_notify_wlan_state_change(hdd_adapter_t *adapter, + eConnectionState old_state, + eConnectionState new_state); + +#else +static inline int hdd_start_tsf_sync(hdd_adapter_t *adapter) +{ + return -ENOTSUPP; +} + +static inline int hdd_stop_tsf_sync(hdd_adapter_t *adapter) +{ + return -ENOTSUPP; +} + +static inline +void hdd_tsf_notify_wlan_state_change(hdd_adapter_t *adapter, + eConnectionState old_state, + eConnectionState new_state) + +{ +} +#endif + #endif diff --git a/CORE/HDD/inc/wlan_hdd_wext.h b/CORE/HDD/inc/wlan_hdd_wext.h index dac20cc0f39b..6a47ede7e6e7 100644 --- a/CORE/HDD/inc/wlan_hdd_wext.h +++ b/CORE/HDD/inc/wlan_hdd_wext.h @@ -258,6 +258,7 @@ typedef enum * TSF_RESET_GPIO_FAIL: GPIO reset fail * TSF_SAP_NOT_STARTED_NO_TSF SAP not started * TSF_NOT_READY: TSF module is not initialized or init failed + * TSF_DISABLED_BY_TSFPLUS: cap_tsf/get_tsf are disabled due to TSF_PLUS */ enum hdd_tsf_get_state { TSF_RETURN = 0, @@ -268,7 +269,8 @@ enum hdd_tsf_get_state { TSF_GET_FAIL, TSF_RESET_GPIO_FAIL, TSF_SAP_NOT_STARTED_NO_TSF, - TSF_NOT_READY + TSF_NOT_READY, + TSF_DISABLED_BY_TSFPLUS }; /** diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 7c632ec814ef..83b0b80add19 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -71,6 +71,8 @@ #include <wlan_logging_sock_svc.h> #include "tl_shim.h" #include "wlan_hdd_oemdata.h" +#include "wlan_hdd_tsf.h" + #include "adf_trace.h" struct ether_addr @@ -156,6 +158,9 @@ v_VOID_t hdd_connSetConnectionState( hdd_adapter_t *pAdapter, hddLog(LOG1, FL("%pS Changed connectionState from oldState:%d to State:%d"), (void *)_RET_IP_, pHddStaCtx->conn_info.connState, connState); + + hdd_tsf_notify_wlan_state_change(pAdapter, + pHddStaCtx->conn_info.connState, connState); pHddStaCtx->conn_info.connState = connState; /* Check is pending ROC request or not when connection state changed */ diff --git a/CORE/HDD/src/wlan_hdd_tsf.c b/CORE/HDD/src/wlan_hdd_tsf.c index f328a4450144..5a73407e2c0d 100644 --- a/CORE/HDD/src/wlan_hdd_tsf.c +++ b/CORE/HDD/src/wlan_hdd_tsf.c @@ -44,6 +44,26 @@ enum hdd_tsf_op_result { HDD_TSF_OP_FAIL }; +#ifdef WLAN_FEATURE_TSF_PLUS +static inline void hdd_set_th_sync_status(hdd_adapter_t *adapter, + bool initialized) +{ + adf_os_atomic_set(&adapter->tsf_sync_ready_flag, + (initialized ? 1 : 0)); +} + +static inline bool hdd_get_th_sync_status(hdd_adapter_t *adapter) +{ + return (!adf_os_atomic_read(&adapter->tsf_sync_ready_flag) == 0); +} + +#else +static inline bool hdd_get_th_sync_status(hdd_adapter_t *adapter) +{ + return true; +} +#endif + static enum hdd_tsf_get_state hdd_tsf_check_conn_state(hdd_adapter_t *adapter) { @@ -87,7 +107,8 @@ static bool hdd_tsf_is_initialized(hdd_adapter_t *adapter) return false; } - if (!adf_os_atomic_read(&hddctx->tsf_ready_flag)) { + if (!adf_os_atomic_read(&hddctx->tsf_ready_flag) || + !hdd_get_th_sync_status(adapter)) { hddLog(VOS_TRACE_LEVEL_ERROR, FL("TSF is not initialized")); return false; @@ -165,6 +186,7 @@ static enum hdd_tsf_op_result hdd_capture_tsf_internal( } hddLog(VOS_TRACE_LEVEL_INFO, FL("-ioctl return cap tsf cmd")); + return HDD_TSF_OP_SUCC; } @@ -236,18 +258,522 @@ static enum hdd_tsf_op_result hdd_indicate_tsf_internal( } } -int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) +#ifdef WLAN_FEATURE_TSF_PLUS +/* unit for target time: us; host time: ns */ +#define HOST_TO_TARGET_TIME_RATIO NSEC_PER_USEC +#define MAX_ALLOWED_DEVIATION_NS (20 * NSEC_PER_MSEC) +#define MAX_CONTINUOUS_ERROR_CNT 3 +#define WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC 500 +#define WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS 100 + +/** + * TS_STATUS - timestamp status + * + * HDD_TS_STATUS_WAITING: one of the stamp-pair + * is not updated + * HDD_TS_STATUS_READY: valid tstamp-pair + * HDD_TS_STATUS_INVALID: invalid tstamp-pair + */ +enum hdd_ts_status { + HDD_TS_STATUS_WAITING, + HDD_TS_STATUS_READY, + HDD_TS_STATUS_INVALID +}; + +static +enum hdd_tsf_op_result __hdd_start_tsf_sync(hdd_adapter_t *adapter) { - return (hdd_capture_tsf_internal(adapter, buf, len) == + VOS_STATUS ret; + + if (!hdd_get_th_sync_status(adapter)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Host Target sync has not initialized")); + return HDD_TSF_OP_FAIL; + } + + ret = vos_timer_start(&adapter->host_target_sync_timer, + WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS); + if (ret != VOS_STATUS_SUCCESS && ret != VOS_STATUS_E_ALREADY) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to start timer, ret: %d"), ret); + return HDD_TSF_OP_FAIL; + } + return HDD_TSF_OP_SUCC; +} + +static +enum hdd_tsf_op_result __hdd_stop_tsf_sync(hdd_adapter_t *adapter) +{ + VOS_STATUS ret; + + if (!hdd_get_th_sync_status(adapter)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Host Target sync has not initialized")); + return HDD_TSF_OP_SUCC; + } + + ret = vos_timer_stop(&adapter->host_target_sync_timer); + if (ret != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to stop timer, ret: %d"), ret); + return HDD_TSF_OP_FAIL; + } + return HDD_TSF_OP_SUCC; +} + +static inline void hdd_reset_timestamps(hdd_adapter_t *adapter) +{ + spin_lock_bh(&adapter->host_target_sync_lock); + adapter->cur_host_time = 0; + adapter->cur_target_time = 0; + adapter->last_host_time = 0; + adapter->last_target_time = 0; + spin_unlock_bh(&adapter->host_target_sync_lock); +} + +/** + * hdd_check_timestamp_status() - return the tstamp status + * + * @last_target_time: the last saved target time + * @last_host_time: the last saved host time + * @cur_target_time : new target time + * @cur_host_time : new host time + * + * This function check the new timstamp-pair(cur_host_time/cur_target_time) + * + * Return: + * HDD_TS_STATUS_WAITING: cur_host_time or cur_host_time is 0 + * HDD_TS_STATUS_READY: cur_target_time/cur_host_time is a valid pair, + * and can be saved + * HDD_TS_STATUS_INVALID: cur_target_time/cur_host_time is a invalid pair, + * should be discard + */ +static +enum hdd_ts_status hdd_check_timestamp_status( + uint64_t last_target_time, + uint64_t last_host_time, + uint64_t cur_target_time, + uint64_t cur_host_time) +{ + uint64_t delta_ns, delta_target_time, delta_host_time; + + /* one or more are not updated, need to wait */ + if (cur_target_time == 0 || cur_host_time == 0) + return HDD_TS_STATUS_WAITING; + + /* init value, it's the first time to update the pair */ + if (last_target_time == 0 && last_host_time == 0) + return HDD_TS_STATUS_READY; + + /* the new values should be greater than the saved values */ + if ((cur_target_time <= last_target_time) || + (cur_host_time <= last_host_time)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Invalid timestamps!last_target_time: %llu;" + "last_host_time: %llu; cur_target_time: %llu;" + "cur_host_time: %llu"), + last_target_time, last_host_time, + cur_target_time, cur_host_time); + return HDD_TS_STATUS_INVALID; + } + + delta_target_time = (cur_target_time - last_target_time) * + HOST_TO_TARGET_TIME_RATIO; + delta_host_time = cur_host_time - last_host_time; + + /* + * DO NOT use abs64() , a big uint64 value might be turned to + * a small int64 value + */ + delta_ns = ((delta_target_time > delta_host_time) ? + (delta_target_time - delta_host_time) : + (delta_host_time - delta_target_time)); + + /* the deviation should be smaller than a threshold */ + if (delta_ns > MAX_ALLOWED_DEVIATION_NS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Invalid timestamps - delta: %llu ns"), delta_ns); + return HDD_TS_STATUS_INVALID; + } + return HDD_TS_STATUS_READY; +} + +static void hdd_update_timestamp(hdd_adapter_t *adapter, + uint64_t target_time, uint64_t host_time) +{ + int interval = 0; + enum hdd_ts_status sync_status; + + if (!adapter) + return; + + spin_lock_bh(&adapter->host_target_sync_lock); + if (target_time > 0) + adapter->cur_target_time = target_time; + if (host_time > 0) + adapter->cur_host_time = host_time; + + sync_status = hdd_check_timestamp_status(adapter->last_target_time, + adapter->last_host_time, + adapter->cur_target_time, + adapter->cur_host_time); + 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->cur_target_time = 0; + adapter->cur_host_time = 0; + break; + } + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Reach the max continuous error count")); + /* + * fall through: + * If reach MAX_CONTINUOUS_ERROR_CNT, treat it as a + * valid pair + */ + case HDD_TS_STATUS_READY: + 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; + hddLog(VOS_TRACE_LEVEL_INFO, + FL("ts-pair updated: target: %llu; host: %llu"), + adapter->last_target_time, + adapter->last_host_time); + interval = WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC * + MSEC_PER_SEC; + adapter->continuous_error_count = 0; + break; + case HDD_TS_STATUS_WAITING: + interval = 0; + break; + } + spin_unlock_bh(&adapter->host_target_sync_lock); + + if (interval > 0) + vos_timer_start(&adapter->host_target_sync_timer, interval); +} + +static inline uint64_t hdd_get_monotonic_host_time(void) +{ + struct timespec ts; + + getrawmonotonic(&ts); + return timespec_to_ns(&ts); +} + +static void hdd_capture_tsf_timer_expired_handler(void *arg) +{ + uint32_t tsf_op_resp; + hdd_adapter_t *adapter; + + if (!arg) + return; + + adapter = (hdd_adapter_t *)arg; + hdd_capture_tsf_internal(adapter, &tsf_op_resp, 1); +} + +static irqreturn_t hdd_tsf_captured_irq_handler(int irq, void *arg) +{ + hdd_adapter_t *adapter; + hdd_context_t *hdd_ctx; + uint64_t host_time; + char *name = NULL; + + if (!arg) + return IRQ_NONE; + + host_time = hdd_get_monotonic_host_time(); + + hdd_ctx = (hdd_context_t *)arg; + + adapter = hdd_ctx->cap_tsf_context; + if (!adapter) + return IRQ_HANDLED; + + if (!hdd_tsf_is_initialized(adapter)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("tsf is not init, ignore irq")); + return IRQ_HANDLED; + } + + hdd_update_timestamp(adapter, 0, host_time); + if (adapter->dev) + name = adapter->dev->name; + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("irq: %d - iface: %s - host_time: %llu"), + irq, (!name ? "none" : name), host_time); + + return IRQ_HANDLED; +} + +static enum hdd_tsf_op_result hdd_tsf_sync_init(hdd_adapter_t *adapter) +{ + VOS_STATUS ret; + hdd_context_t *hddctx; + + if (!adapter) + return HDD_TSF_OP_FAIL; + + hddctx = WLAN_HDD_GET_CTX(adapter); + if (!hddctx) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("invalid hdd context")); + return HDD_TSF_OP_FAIL; + } + + if (!adf_os_atomic_read(&hddctx->tsf_ready_flag)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("TSF feature has NOT been initialized")); + return HDD_TSF_OP_FAIL; + } + + if (hdd_get_th_sync_status(adapter)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Host Target sync has been initialized!!")); + return HDD_TSF_OP_SUCC; + } + + spin_lock_init(&adapter->host_target_sync_lock); + + hdd_reset_timestamps(adapter); + + ret = vos_timer_init(&adapter->host_target_sync_timer, + VOS_TIMER_TYPE_SW, + hdd_capture_tsf_timer_expired_handler, + (void *)adapter); + if (ret != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to init timer, ret: %d"), ret); + goto fail; + } + + hdd_set_th_sync_status(adapter, true); + + return HDD_TSF_OP_SUCC; +fail: + hdd_set_th_sync_status(adapter, false); + return HDD_TSF_OP_FAIL; +} + +static enum hdd_tsf_op_result hdd_tsf_sync_deinit(hdd_adapter_t *adapter) +{ + VOS_STATUS ret; + hdd_context_t *hddctx; + + if (!adapter) + return HDD_TSF_OP_FAIL; + + if (!hdd_get_th_sync_status(adapter)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Host Target sync has not been initialized!!")); + return HDD_TSF_OP_SUCC; + } + + hdd_set_th_sync_status(adapter, false); + + ret = vos_timer_destroy(&adapter->host_target_sync_timer); + if (ret != VOS_STATUS_SUCCESS) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to destroy timer, ret: %d"), ret); + + hddctx = WLAN_HDD_GET_CTX(adapter); + + /* reset the cap_tsf flag and gpio if needed */ + if (hddctx && adf_os_atomic_read(&hddctx->cap_tsf_flag) && + hddctx->cap_tsf_context == adapter) { + int reset_ret = hdd_reset_tsf_gpio(adapter); + + if (reset_ret) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to reset tsf gpio, ret:%d"), + reset_ret); + hddctx->cap_tsf_context = NULL; + adf_os_atomic_set(&hddctx->cap_tsf_flag, 0); + } + + hdd_reset_timestamps(adapter); + return HDD_TSF_OP_SUCC; +} + +static inline void hdd_update_tsf(hdd_adapter_t *adapter, uint64_t tsf) +{ + uint32_t tsf_op_resp[3]; + + hdd_indicate_tsf_internal(adapter, tsf_op_resp, 3); + hdd_update_timestamp(adapter, tsf, 0); +} + +int hdd_start_tsf_sync(hdd_adapter_t *adapter) +{ + enum hdd_tsf_op_result ret; + + if (!adapter) + return -EINVAL; + + ret = hdd_tsf_sync_init(adapter); + if (ret != HDD_TSF_OP_SUCC) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to init tsf sync, ret: %d"), ret); + return -EINVAL; + } + + return (__hdd_start_tsf_sync(adapter) == HDD_TSF_OP_SUCC ? 0 : -EINVAL); } -int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) +int hdd_stop_tsf_sync(hdd_adapter_t *adapter) +{ + enum hdd_tsf_op_result ret; + + if (!adapter) + return -EINVAL; + + ret = __hdd_stop_tsf_sync(adapter); + if (ret != HDD_TSF_OP_SUCC) + return -EINVAL; + + ret = hdd_tsf_sync_deinit(adapter); + if (ret != HDD_TSF_OP_SUCC) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to deinit tsf sync, ret: %d"), ret); + return -EINVAL; + } + return 0; +} + +static inline int __hdd_capture_tsf(hdd_adapter_t *adapter, + uint32_t *buf, int len) +{ + if (!adapter || !buf) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("invalid pointer")); + return -EINVAL; + } + + if (len != 1) + return -EINVAL; + + buf[0] = TSF_DISABLED_BY_TSFPLUS; + + return 0; +} + +static inline int __hdd_indicate_tsf(hdd_adapter_t *adapter, + uint32_t *buf, int len) +{ + if (!adapter || !buf) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("invalid pointer")); + return -EINVAL; + } + + if (len != 3) + return -EINVAL; + + buf[0] = TSF_DISABLED_BY_TSFPLUS; + buf[1] = 0; + buf[2] = 0; + + return 0; +} + +static inline +enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(hdd_context_t *hdd_ctx) +{ + int ret; + + ret = cnss_common_register_tsf_captured_handler( + hdd_ctx->parent_dev, + hdd_tsf_captured_irq_handler, + (void *)hdd_ctx); + if (ret != 0) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to register irq handler: %d"), ret); + return HDD_TSF_OP_FAIL; + } + return HDD_TSF_OP_SUCC; +} + +static inline +enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(hdd_context_t *hdd_ctx) +{ + int ret; + + ret = cnss_common_unregister_tsf_captured_handler( + hdd_ctx->parent_dev, + (void *)hdd_ctx); + if (ret != 0) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to unregister irq handler, ret:%d"), + ret); + ret = HDD_TSF_OP_FAIL; + } + + return HDD_TSF_OP_SUCC; +} + +void hdd_tsf_notify_wlan_state_change(hdd_adapter_t *adapter, + eConnectionState old_state, + eConnectionState new_state) +{ + if (!adapter) + return; + + if (old_state != eConnectionState_Associated && + new_state == eConnectionState_Associated) + hdd_start_tsf_sync(adapter); + else if (old_state == eConnectionState_Associated && + new_state != eConnectionState_Associated) + hdd_stop_tsf_sync(adapter); +} +#else +static inline void hdd_update_tsf(hdd_adapter_t *adapter, uint64_t tsf) +{ +} + +static inline int __hdd_indicate_tsf(hdd_adapter_t *adapter, + uint32_t *buf, int len) { return (hdd_indicate_tsf_internal(adapter, buf, len) == HDD_TSF_OP_SUCC ? 0 : -EINVAL); } +static inline int __hdd_capture_tsf(hdd_adapter_t *adapter, + uint32_t *buf, int len) +{ + return (hdd_capture_tsf_internal(adapter, buf, len) == + HDD_TSF_OP_SUCC ? 0 : -EINVAL); +} + +static inline +enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(hdd_context_t *hdd_ctx) +{ + return HDD_TSF_OP_SUCC; +} + +static inline +enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(hdd_context_t *hdd_ctx) +{ + return HDD_TSF_OP_SUCC; +} +#endif /* WLAN_FEATURE_TSF_PLUS */ + +int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) +{ + return __hdd_capture_tsf(adapter, buf, len); +} + +int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) +{ + return __hdd_indicate_tsf(adapter, buf, len); +} + /** * hdd_get_tsf_cb() - handle tsf callback * @@ -299,6 +825,8 @@ static int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf) adapter->cur_target_time = ((uint64_t)ptsf->tsf_high << 32 | ptsf->tsf_low); + hdd_update_tsf(adapter, adapter->cur_target_time); + hddLog(VOS_TRACE_LEVEL_INFO, FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"), ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high); @@ -335,6 +863,9 @@ void wlan_hdd_tsf_init(hdd_context_t *hdd_ctx) goto fail; } + if (wlan_hdd_tsf_plus_init(hdd_ctx) != HDD_TSF_OP_SUCC) + goto fail; + return; fail: @@ -358,6 +889,7 @@ void wlan_hdd_tsf_deinit(hdd_context_t *hdd_ctx) hal_status); } + wlan_hdd_tsf_plus_deinit(hdd_ctx); adf_os_atomic_set(&hdd_ctx->tsf_ready_flag, 0); adf_os_atomic_set(&hdd_ctx->cap_tsf_flag, 0); } @@ -48,6 +48,12 @@ ifeq ($(KERNEL_BUILD), 0) CONFIG_MOBILE_ROUTER := y endif + ifeq ($(CONFIG_ARCH_MSM8917), y) + ifeq ($(CONFIG_ROME_IF), sdio) + CONFIG_WLAN_SYNC_TSF_PLUS := y + endif + endif + # As per target team, build is done as follows: # Defconfig : build with default flags # Slub : defconfig + CONFIG_SLUB_DEBUG=y + @@ -449,6 +455,10 @@ ifeq ($(CONFIG_QCOM_TDLS),y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tdls.o endif +ifeq ($(CONFIG_WLAN_SYNC_TSF_PLUS), y) +CONFIG_WLAN_SYNC_TSF := y +endif + ifeq ($(CONFIG_WLAN_SYNC_TSF),y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tsf.o endif @@ -1553,6 +1563,10 @@ ifeq ($(CONFIG_WLAN_SYNC_TSF),y) CDEFINES += -DWLAN_FEATURE_TSF endif +ifeq ($(CONFIG_WLAN_SYNC_TSF_PLUS), y) +CDEFINES += -DWLAN_FEATURE_TSF_PLUS +endif + # Enable target dump for non-qualcomm platform ifeq ($(CONFIG_NON_QC_PLATFORM), y) CDEFINES += -DCONFIG_NON_QC_PLATFORM |
