summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbings <bings@codeaurora.org>2019-01-21 14:50:20 +0800
committerbings <bings@codeaurora.org>2019-01-29 15:45:44 +0800
commit9b71f4ece3d8e80c46645d84d170f6eed5153a60 (patch)
treea630589af122db927090f79d97378f3ae99a6795
parent783763b498e3876f3694b69237d23ee06ffb9dd0 (diff)
qcacld-2.0: Get tsf by register
If the platform does not have free GPIO for TSF, please get tsf by reading TSF register. FW will update TSF ID information after vdev up. With TSF ID driver can read specified tsf register directly. Change-Id: I0e2cfca1ff872d337ec16e732f45f214e37bac46 CRs-Fixed: 2384923
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg.h20
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h26
-rw-r--r--CORE/HDD/inc/wlan_hdd_tsf.h7
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c7
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c2
-rw-r--r--CORE/HDD/src/wlan_hdd_tsf.c278
-rw-r--r--CORE/MAC/inc/sirApi.h6
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.c9
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.h12
-rw-r--r--CORE/SERVICES/HIF/USB/if_usb.c7
-rw-r--r--CORE/SERVICES/HIF/USB/if_usb.h12
-rw-r--r--CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c9
-rw-r--r--CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h12
-rw-r--r--CORE/SERVICES/WMA/wma.c4
14 files changed, 368 insertions, 43 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 9abdef519f3f..bf4f9273fc62 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -4202,6 +4202,25 @@ FG_BTC_BT_INTERVAL_PAGE_P2P_STA_DEFAULT
#define CFG_SET_TSF_GPIO_PIN_HOST_MAX (254)
#define CFG_SET_TSF_GPIO_PIN_HOST_DEFAULT (45)
+/*
+ * <ini>
+ * gtsf_by_register - get tsf by register
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to get tsf by register
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_GET_TSF_BY_REGISTER_NAME "gtsf_by_register"
+#define CFG_GET_TSF_BY_REGISTER_MIN (0)
+#define CFG_GET_TSF_BY_REGISTER_MAX (1)
+#define CFG_GET_TSF_BY_REGISTER_DEFAULT (0)
+
#ifdef WLAN_FEATURE_TSF_PLUS
/* PTP options */
#define CFG_SET_TSF_PTP_OPT_NAME "gtsf_ptp_options"
@@ -6312,6 +6331,7 @@ struct hdd_config {
#ifdef WLAN_FEATURE_TSF
uint32_t tsf_gpio_pin;
uint32_t tsf_gpio_pin_host;
+ uint8_t tsf_by_register;
#ifdef WLAN_FEATURE_TSF_PLUS
uint8_t tsf_ptp_options;
#endif /* WLAN_FEATURE_TSF_PLUS */
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index d60734a149af..5f40b688310e 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1177,6 +1177,19 @@ struct hdd_netif_queue_history {
uint32_t pause_map;
};
+/**
+ * enum HDD_TSF_ID - TSF ID
+ * HDD_TSF1 - TSF 1
+ * HDD_TSF2 - TSF 2
+ * HDD_TSF_NUM_MAX - max tsf num
+ * HDD_TSF_INVALID - invalid tsf id
+ */
+typedef enum {
+ HDD_TSF1,
+ HDD_TSF2,
+ HDD_TSF_NUM_MAX,
+ HDD_TSF_INVALID,
+}HDD_TSF_ID;
struct hdd_adapter_s
{
@@ -1334,16 +1347,20 @@ struct hdd_adapter_s
}sessionCtx;
#ifdef WLAN_FEATURE_TSF
+#define MAX_INVALD_TIME_NUM 4
/* tsf value get from firmware */
uint64_t cur_target_time;
+ uint64_t cur_host_time;
+ uint64_t last_host_time;
+ uint64_t last_target_time;
vos_timer_t host_capture_req_timer;
+ uint64_t invalid_target_time[MAX_INVALD_TIME_NUM];
+ uint64_t invalid_host_time[MAX_INVALD_TIME_NUM];
+ uint8_t invalid_time_num;
#ifdef WLAN_FEATURE_TSF_PLUS
/* spin lock for read/write timestamps */
adf_os_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 */
@@ -1443,6 +1460,7 @@ struct hdd_adapter_s
adf_os_time_t total_unpause_time;
uint8_t history_index;
+ HDD_TSF_ID tsf_id;
struct hdd_netif_queue_history
queue_oper_history[WLAN_HDD_MAX_HISTORY_ENTRY];
struct hdd_netif_queue_stats queue_oper_stats[WLAN_REASON_TYPE_MAX];
diff --git a/CORE/HDD/inc/wlan_hdd_tsf.h b/CORE/HDD/inc/wlan_hdd_tsf.h
index a1a329b87fc4..2ea0a8c2a360 100644
--- a/CORE/HDD/inc/wlan_hdd_tsf.h
+++ b/CORE/HDD/inc/wlan_hdd_tsf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015,2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015,2018-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -44,6 +44,11 @@
#ifdef WLAN_FEATURE_TSF
+#define REG_TSF1_L 0x1054
+#define REG_TSF1_H 0x1058
+#define REG_TSF2_L 0x10d4
+#define REG_TSF2_H 0x10d8
+
/**
* wlan_hdd_tsf_init() - set gpio and callbacks for
* capturing tsf and init tsf_plus
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index f7ffdb69533d..7c00814f86c3 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -4587,6 +4587,13 @@ REG_TABLE_ENTRY g_registry_table[] =
CFG_SET_TSF_GPIO_PIN_HOST_MIN,
CFG_SET_TSF_GPIO_PIN_HOST_MAX),
+ REG_VARIABLE(CFG_GET_TSF_BY_REGISTER_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, tsf_by_register,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_GET_TSF_BY_REGISTER_DEFAULT,
+ CFG_GET_TSF_BY_REGISTER_MIN,
+ CFG_GET_TSF_BY_REGISTER_MAX),
+
REG_VARIABLE(CFG_SET_TSF_GPIO_PIN_NAME, WLAN_PARAM_Integer,
hdd_config_t, tsf_gpio_pin,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 85cfccfc4e04..5efe4ebfe02f 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -12177,6 +12177,8 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx,
/* Adapter successfully added. Increment the vdev count */
hdd_ctx->current_intf_count++;
+ adapter->tsf_id = HDD_TSF2;
+
hddLog(VOS_TRACE_LEVEL_DEBUG,
"%s: current_intf_count=%d", __func__,
hdd_ctx->current_intf_count);
diff --git a/CORE/HDD/src/wlan_hdd_tsf.c b/CORE/HDD/src/wlan_hdd_tsf.c
index 6ad7f14af2c6..c6fb7f8c983b 100644
--- a/CORE/HDD/src/wlan_hdd_tsf.c
+++ b/CORE/HDD/src/wlan_hdd_tsf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -32,6 +32,13 @@
#include "wlan_hdd_main.h"
#include "wlan_hdd_tsf.h"
#include "wma_api.h"
+#if defined(HIF_PCI)
+#include "if_pci.h"
+#elif defined(HIF_USB)
+#include "if_usb.h"
+#elif defined(HIF_SDIO)
+#include "if_ath_sdio.h"
+#endif
#include <linux/errqueue.h>
#if defined(CONFIG_NON_QC_PLATFORM)
#include <linux/gpio.h>
@@ -651,6 +658,133 @@ static inline uint64_t hdd_get_monotonic_host_time(hdd_context_t *hdd_ctx)
ktime_get_ns() : ktime_get_real_ns());
}
+/**
+ * is_target_host_valid() - is target tsf valid or not
+ * @delt_host_time: current host time - last golden host time
+ * @delt_target_time: current target time - last golden target time
+ *
+ * Return: TRUE if target tsf is valid
+ */
+static inline bool is_target_host_valid(uint64_t delt_host_time,
+ uint64_t delt_target_time)
+{
+ if ((delt_target_time * HOST_TO_TARGET_TIME_RATIO >
+ (delt_host_time - delt_host_time/100)) &&
+ (delt_target_time * HOST_TO_TARGET_TIME_RATIO <
+ (delt_host_time + delt_host_time/100)))
+ return true;
+ else
+ return false;
+}
+
+/**
+ * update_target_host_time - update new captured target tsf
+ * @adapter: pointer to adapter
+ *
+ * Return True if current target tsf can be set as golden tsf.
+ */
+static bool update_target_host_time(hdd_adapter_t *adapter)
+{
+ uint64_t delt_host_time = 0;
+ uint64_t delt_target_time = 0;
+ int num_index = 0;
+ int i = 0;
+ bool update_time = false;
+
+ delt_host_time = adapter->cur_host_time - adapter->last_host_time;
+ delt_target_time = adapter->cur_target_time - adapter->last_target_time;
+
+ if ((!adapter->last_target_time) ||
+ is_target_host_valid(delt_host_time, delt_target_time)) {
+ adapter->last_host_time = adapter->cur_host_time;
+ adapter->last_target_time = adapter->cur_target_time;
+ adapter->invalid_time_num = 0;
+ return true;
+ } else if (adapter->invalid_time_num >= MAX_INVALD_TIME_NUM) {
+ update_time = true;
+ for (i = 0; i < MAX_INVALD_TIME_NUM; i++) {
+ num_index = (adapter->invalid_time_num - i - 1) %
+ MAX_INVALD_TIME_NUM;
+ delt_host_time = adapter->cur_host_time -
+ adapter->invalid_host_time[num_index];
+ delt_target_time = adapter->cur_target_time -
+ adapter->invalid_target_time[num_index];
+ if (!is_target_host_valid(delt_host_time,
+ delt_target_time)) {
+ update_time = false;
+ break;
+ }
+ }
+ }
+
+ if (update_time) {
+ adapter->last_host_time = adapter->cur_host_time;
+ adapter->last_target_time = adapter->cur_target_time;
+ adapter->invalid_time_num = 0;
+ return true;
+ } else {
+ num_index = adapter->invalid_time_num % MAX_INVALD_TIME_NUM;
+ adapter->invalid_host_time[num_index] = adapter->cur_host_time;
+ adapter->invalid_target_time[num_index] =
+ adapter->cur_target_time;
+ adapter->invalid_time_num++;
+ return false;
+ }
+}
+
+/**
+ * hdd_get_tsf_by_register() - get tsf by register
+ * @adapter: pointer to adapter
+ * @host_time: current host time
+ * @target_time: current target time.
+ *
+ * Return 0 if succeeds
+ */
+static inline int32_t hdd_get_tsf_by_register(hdd_adapter_t *adapter,
+ uint64_t host_time, uint64_t *target_time)
+{
+ v_PVOID_t pHifContext = NULL;
+ v_CONTEXT_t pVosContext = NULL;
+ uint32_t datal;
+ uint32_t datah;
+ uint32_t tsf_id = adapter->tsf_id;
+ int32_t ret = 0;
+
+ pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+ if(!pVosContext)
+ return -EFAULT;
+ pHifContext = vos_get_context(VOS_MODULE_ID_HIF, pVosContext);
+ if (!pHifContext)
+ return -EFAULT;
+
+ if (tsf_id == HDD_TSF1) {
+ hif_get_reg(pHifContext, REG_TSF1_L, &datal);
+ hif_get_reg(pHifContext, REG_TSF1_H, &datah);
+ *target_time = datal + ((uint64_t)datah << 32);
+ } else if (tsf_id == HDD_TSF2) {
+ hif_get_reg(pHifContext, REG_TSF2_L, &datal);
+ hif_get_reg(pHifContext, REG_TSF2_H, &datah);
+ *target_time = datal + ((uint64_t)datah << 32);
+ } else {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid tsf id %u"), tsf_id);
+ return -EFAULT;
+ }
+
+ adapter->cur_host_time = host_time;
+ if (!ret)
+ adapter->cur_target_time = *target_time;
+
+ if (!ret && update_target_host_time(adapter))
+ *target_time = adapter->cur_target_time;
+ else
+ *target_time = ((adapter->cur_host_time -
+ adapter->last_host_time) /
+ HOST_TO_TARGET_TIME_RATIO) +
+ adapter->last_target_time;
+
+ return 0;
+}
+
static ssize_t __hdd_wlan_tsf_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -668,10 +802,6 @@ static ssize_t __hdd_wlan_tsf_show(struct device *dev,
if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
return scnprintf(buf, PAGE_SIZE, "Invalid device\n");
- if (!hdd_get_th_sync_status(adapter))
- return scnprintf(buf, PAGE_SIZE,
- "TSF sync is not initialized\n");
-
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (!hdd_ctx)
return scnprintf(buf, PAGE_SIZE, "Invalid HDD context\n");
@@ -692,12 +822,25 @@ static ssize_t __hdd_wlan_tsf_show(struct device *dev,
}
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");
- else
- size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n",
- buf, target_time, host_time, bssid);
+ if (hdd_ctx->cfg_ini->tsf_by_register) {
+ if (hdd_get_tsf_by_register(adapter, host_time,
+ &target_time))
+ size = scnprintf(buf, PAGE_SIZE, "Invalid timestamp\n");
+ else
+ size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n",
+ buf, target_time, host_time, bssid);
+ } else {
+ if (!hdd_get_th_sync_status(adapter))
+ return scnprintf(buf, PAGE_SIZE,
+ "TSF sync is not initialized\n");
+
+ if (hdd_get_targettime_from_hosttime(adapter, host_time,
+ &target_time))
+ size = scnprintf(buf, PAGE_SIZE, "Invalid timestamp\n");
+ else
+ size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n",
+ buf, target_time, host_time, bssid);
+ }
return size;
}
@@ -818,7 +961,6 @@ static enum hdd_tsf_op_result hdd_tsf_sync_init(hdd_adapter_t *adapter)
{
VOS_STATUS ret;
hdd_context_t *hddctx;
- struct net_device *net_dev;
if (!adapter)
return HDD_TSF_OP_FAIL;
@@ -856,9 +998,6 @@ static enum hdd_tsf_op_result hdd_tsf_sync_init(hdd_adapter_t *adapter)
goto fail;
}
- net_dev = adapter->dev;
- 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);
return HDD_TSF_OP_SUCC;
@@ -871,7 +1010,6 @@ static enum hdd_tsf_op_result hdd_tsf_sync_deinit(hdd_adapter_t *adapter)
{
VOS_STATUS ret;
hdd_context_t *hddctx;
- struct net_device *net_dev;
if (!adapter)
return HDD_TSF_OP_FAIL;
@@ -906,12 +1044,6 @@ static enum hdd_tsf_op_result hdd_tsf_sync_deinit(hdd_adapter_t *adapter)
hdd_reset_timestamps(adapter);
- net_dev = adapter->dev;
- if (net_dev && HDD_TSF_IS_DBG_FS_SET(hddctx)) {
- struct device *dev = &net_dev->dev;
-
- device_remove_file(dev, &dev_attr_tsf);
- }
return HDD_TSF_OP_SUCC;
}
@@ -951,10 +1083,20 @@ enum hdd_tsf_op_result hdd_netbuf_timestamp(adf_nbuf_t netbuf,
int hdd_start_tsf_sync(hdd_adapter_t *adapter)
{
enum hdd_tsf_op_result ret;
+ hdd_context_t *hddctx;
+ struct net_device *net_dev;
if (!adapter)
return -EINVAL;
+ net_dev = adapter->dev;
+ hddctx = WLAN_HDD_GET_CTX(adapter);
+ if (net_dev && HDD_TSF_IS_DBG_FS_SET(hddctx))
+ device_create_file(&net_dev->dev, &dev_attr_tsf);
+
+ if (hddctx->cfg_ini->tsf_by_register)
+ return 0;
+
ret = hdd_tsf_sync_init(adapter);
if (ret != HDD_TSF_OP_SUCC) {
hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -969,10 +1111,22 @@ int hdd_start_tsf_sync(hdd_adapter_t *adapter)
int hdd_stop_tsf_sync(hdd_adapter_t *adapter)
{
enum hdd_tsf_op_result ret;
+ hdd_context_t *hddctx;
+ struct net_device *net_dev;
if (!adapter)
return -EINVAL;
+ hddctx = WLAN_HDD_GET_CTX(adapter);
+ net_dev = adapter->dev;
+ if (net_dev && HDD_TSF_IS_DBG_FS_SET(hddctx)) {
+ struct device *dev = &net_dev->dev;
+
+ device_remove_file(dev, &dev_attr_tsf);
+ }
+ if (hddctx->cfg_ini->tsf_by_register)
+ return 0;
+
ret = __hdd_stop_tsf_sync(adapter);
if (ret != HDD_TSF_OP_SUCC)
return -EINVAL;
@@ -1372,12 +1526,24 @@ static int wlan_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
}
host_time = hdd_get_monotonic_host_time(pHddCtx);
- if (hdd_get_targettime_from_hosttime(adapter, host_time,
- &target_time)) {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("get invalid target timestamp"));
- return -EINVAL;
+ if (pHddCtx->cfg_ini->tsf_by_register) {
+ if (hdd_get_tsf_by_register(adapter, host_time,
+ &target_time)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("get invalid target timestamp"));
+ return -EINVAL;
+ } else {
+ *ts = ns_to_timespec(target_time * NSEC_PER_USEC);
+ }
} else {
- *ts = ns_to_timespec(target_time * NSEC_PER_USEC);
+ if (hdd_get_targettime_from_hosttime(adapter, host_time,
+ &target_time)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("get invalid target timestamp"));
+ return -EINVAL;
+ } else {
+ *ts = ns_to_timespec(target_time * NSEC_PER_USEC);
+ }
}
return 0;
@@ -1440,12 +1606,24 @@ static int wlan_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
}
host_time = hdd_get_monotonic_host_time(pHddCtx);
- if (hdd_get_targettime_from_hosttime(adapter, host_time,
- &target_time)) {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("get invalid target timestamp"));
- return -EINVAL;
+ if (pHddCtx->cfg_ini->tsf_by_register) {
+ if (hdd_get_tsf_by_register(adapter, host_time,
+ &target_time)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("get invalid target timestamp"));
+ return -EINVAL;
+ } else {
+ *ts = ns_to_timespec64(target_time * NSEC_PER_USEC);
+ }
} else {
- *ts = ns_to_timespec64(target_time * NSEC_PER_USEC);
+ if (hdd_get_targettime_from_hosttime(adapter, host_time,
+ &target_time)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("get invalid target timestamp"));
+ return -EINVAL;
+ } else {
+ *ts = ns_to_timespec64(target_time * NSEC_PER_USEC);
+ }
}
return 0;
@@ -1521,6 +1699,22 @@ static int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
return -EINVAL;
}
+ if (hddctx->cfg_ini->tsf_by_register) {
+ if (ptsf->tsf_id_valid) {
+ adapter->tsf_id = ptsf->tsf_id;
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("vdev id %u, tsf id %u"),
+ ptsf->vdev_id, ptsf->tsf_id);
+ return 0;
+ } else {
+ adapter->tsf_id = HDD_TSF_INVALID;
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("vdev id %u, invalid tsf id"),
+ ptsf->vdev_id);
+ return -EINVAL;
+ }
+ }
+
if (!hdd_tsf_is_initialized(adapter)) {
hddLog(VOS_TRACE_LEVEL_ERROR,
FL("tsf is not init, ignore tsf event"));
@@ -1563,6 +1757,17 @@ void wlan_hdd_tsf_init(hdd_context_t *hdd_ctx)
if (!hdd_ctx)
return;
+ if (hdd_ctx->cfg_ini->tsf_by_register) {
+ wlan_hdd_phc_init(hdd_ctx);
+ hal_status = sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb,
+ hdd_ctx);
+ if (eHAL_STATUS_SUCCESS != hal_status)
+ hddLog(LOGE, FL("get tsf id cb failed, status: %d"),
+ hal_status);
+
+ return;
+ }
+
if (adf_os_atomic_inc_return(&hdd_ctx->tsf_ready_flag) > 1)
return;
@@ -1609,6 +1814,15 @@ void wlan_hdd_tsf_deinit(hdd_context_t *hdd_ctx)
if (!hdd_ctx)
return;
+ if (hdd_ctx->cfg_ini->tsf_by_register) {
+ wlan_hdd_phc_deinit(hdd_ctx);
+ hal_status = sme_set_tsfcb(hdd_ctx->hHal, NULL, NULL);
+ if (eHAL_STATUS_SUCCESS != hal_status)
+ hddLog(LOGE, FL("reset tsf cb failed, status: %d"),
+ hal_status);
+ return;
+ }
+
if (!adf_os_atomic_read(&hdd_ctx->tsf_ready_flag))
return;
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index a023876cdf7f..7193c50b8f57 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -7193,6 +7193,8 @@ struct sblock_info {
* @vdev_id: vdev id
* @tsf_low: low 32bits of tsf
* @tsf_high: high 32bits of tsf
+ * @tsf_id: tsf id
+ * @tsf_id_valid: valid tsf id or not
*
* driver use this struct to store the tsf info
*/
@@ -7200,6 +7202,8 @@ struct stsf {
uint32_t vdev_id;
uint32_t tsf_low;
uint32_t tsf_high;
+ uint32_t tsf_id;
+ uint32_t tsf_id_valid;
};
#ifdef WLAN_FEATURE_MOTION_DETECTION
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c
index 9a937b60eda8..baa582ff9352 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -3406,6 +3406,13 @@ void hif_pci_save_htc_htt_config_endpoint(int htc_endpoint)
scn->hif_sc->htc_endpoint = htc_endpoint;
}
+void hif_get_reg(void *ol_sc, u32 address, u32 *data)
+{
+ struct ol_softc *scn = (struct ol_softc *)ol_sc;
+
+ HIFDiagReadAccess(scn->hif_hdl, address, data);
+}
+
void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision)
{
*version = ((struct ol_softc *)ol_sc)->target_version;
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.h b/CORE/SERVICES/HIF/PCIe/if_pci.h
index 4ab0749b832e..5849e3fccee5 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.h
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 2018-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -176,6 +176,16 @@ void hif_deinit_adf_ctx(void *ol_sc);
void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision);
void hif_set_fw_info(void *ol_sc, u32 target_fw_version);
+/**
+ * hif_get_reg() - get register value
+ * @ol_sc: pointer to ol_sc
+ * @address: register address
+ * @data register value
+ *
+ * Return NULL
+ */
+void hif_get_reg(void *ol_sc, u32 address, u32 *data);
+
#ifdef IPA_UC_OFFLOAD
/*
* Micro controller needs PCI BAR address to access CE register
diff --git a/CORE/SERVICES/HIF/USB/if_usb.c b/CORE/SERVICES/HIF/USB/if_usb.c
index 455f4041724c..56ffd63ff055 100644
--- a/CORE/SERVICES/HIF/USB/if_usb.c
+++ b/CORE/SERVICES/HIF/USB/if_usb.c
@@ -648,6 +648,13 @@ void hif_reset_soc(void *ol_sc)
/* TODO */
}
+void hif_get_reg(void *ol_sc, u32 address, u32 *data)
+{
+ struct ol_softc *scn = (struct ol_softc *)ol_sc;
+
+ HIFDiagReadAccess(scn->hif_hdl, address, data);
+}
+
void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision)
{
u_int32_t hif_type, target_type;
diff --git a/CORE/SERVICES/HIF/USB/if_usb.h b/CORE/SERVICES/HIF/USB/if_usb.h
index 1cd06d2f0c91..51e37c976f48 100644
--- a/CORE/SERVICES/HIF/USB/if_usb.h
+++ b/CORE/SERVICES/HIF/USB/if_usb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014 2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -99,6 +99,16 @@ void hif_disable_isr(void *ol_sc);
void hif_reset_soc(void *ol_sc);
void hif_deinit_adf_ctx(void *ol_sc);
+/**
+ * hif_get_reg() - get register value
+ * @ol_sc: pointer to ol_sc
+ * @address: register address
+ * @data register value
+ *
+ * Return NULL
+ */
+void hif_get_reg(void *ol_sc, u32 address, u32 *data);
+
void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision);
void hif_set_fw_info(void *ol_sc, u32 target_fw_version);
#endif /* __ATH_USB_H__ */
diff --git a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c
index 12c5fd47dbb3..0da4defafc3e 100644
--- a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c
+++ b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -481,6 +481,13 @@ void hif_reset_soc(void *ol_sc)
ENTER("- dummy function!");
}
+void hif_get_reg(void *ol_sc, u32 address, u32 *data)
+{
+ struct ol_softc *scn = (struct ol_softc *)ol_sc;
+
+ HIFDiagReadAccess(scn->hif_hdl, address, data);
+}
+
void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision)
{
struct ol_softc *ol_sc_local = (struct ol_softc *)ol_sc;
diff --git a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h
index 198d40c2c907..ccb0d3cec26e 100644
--- a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h
+++ b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014 2018-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -104,6 +104,16 @@ void hif_reset_soc(void *ol_sc);
void hif_register_tbl_attach(u32 hif_type);
void target_register_tbl_attach(u32 target_type);
+/**
+ * hif_get_reg() - get register value
+ * @ol_sc: pointer to ol_sc
+ * @address: register address
+ * @data register value
+ *
+ * Return NULL
+ */
+void hif_get_reg(void *ol_sc, u32 address, u32 *data);
+
void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision);
void hif_set_fw_info(void *ol_sc, u32 target_fw_version);
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 06bad7751882..ed456dd6f82e 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -37087,10 +37087,14 @@ static int wma_vdev_tsf_handler(void *handle, uint8_t *data,
ptsf->vdev_id = tsf_event->vdev_id;
ptsf->tsf_low = tsf_event->tsf_low;
ptsf->tsf_high = tsf_event->tsf_high;
+ ptsf->tsf_id = tsf_event->tsf_id;
+ ptsf->tsf_id_valid = tsf_event->tsf_id_valid;
WMA_LOGD("%s: receive WMI_VDEV_TSF_REPORT_EVENTID ", __func__);
WMA_LOGD("%s: vdev_id = %u,tsf_low =%u, tsf_high = %u", __func__,
ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high);
+ WMA_LOGD("%s: vdev_id = %u,tsf_id =%u, tsf_id_valid = %u", __func__,
+ ptsf->vdev_id, ptsf->tsf_id, ptsf->tsf_id_valid);
vos_msg.type = eWNI_SME_TSF_EVENT;
vos_msg.bodyptr = ptsf;