/*
 * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/**
 * wlan_hdd_tsf.c - WLAN Host Device Driver tsf related implementation
 */

#include "wlan_hdd_main.h"
#include "wlan_hdd_tsf.h"
#include "wma_api.h"
#include <linux/errqueue.h>

/**
 * enum hdd_tsf_op_result - result of tsf operation
 *
 * HDD_TSF_OP_SUCC:  succeed
 * HDD_TSF_OP_FAIL:  fail
 */
enum hdd_tsf_op_result {
	HDD_TSF_OP_SUCC,
	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)
{
	enum hdd_tsf_get_state ret = TSF_RETURN;
	hdd_station_ctx_t *hdd_sta_ctx;

	if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
			adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
		hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
		if (hdd_sta_ctx->conn_info.connState !=
				eConnectionState_Associated) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("failed to cap tsf, not connect with ap"));
			ret = TSF_STA_NOT_CONNECTED_NO_TSF;
		}
	} else if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
				adapter->device_mode == WLAN_HDD_P2P_GO) &&
			!(test_bit(SOFTAP_BSS_STARTED,
					&adapter->event_flags))) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			FL("Soft AP / P2p GO not beaconing"));
		ret = TSF_SAP_NOT_STARTED_NO_TSF;
	}
	return ret;
}

static bool hdd_tsf_is_initialized(hdd_adapter_t *adapter)
{
	hdd_context_t *hddctx;

	if (!adapter) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			FL("invalid adapter"));
		return false;
	}

	hddctx = WLAN_HDD_GET_CTX(adapter);
	if (!hddctx) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("invalid hdd context"));
		return false;
	}

	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;
	}

	return true;
}

static inline int hdd_reset_tsf_gpio(hdd_adapter_t *adapter)
{
	return process_wma_set_command((int)adapter->sessionId,
			(int)GEN_PARAM_RESET_TSF_GPIO,
			adapter->sessionId,
			GEN_CMD);
}

static enum hdd_tsf_op_result hdd_capture_tsf_internal(
	hdd_adapter_t *adapter, uint32_t *buf, int len)
{
	int ret;
	hdd_context_t *hddctx;

	if (adapter == NULL || buf == NULL) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("invalid pointer"));
		return HDD_TSF_OP_FAIL;
	}

	if (len != 1)
		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 (!hdd_tsf_is_initialized(adapter)) {
		buf[0] = TSF_NOT_READY;
		return HDD_TSF_OP_SUCC;
	}

	buf[0] = hdd_tsf_check_conn_state(adapter);
	if (buf[0] != TSF_RETURN)
		return HDD_TSF_OP_SUCC;

	if (adf_os_atomic_inc_return(&hddctx->cap_tsf_flag) > 1) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("current in capture state"));
		buf[0] = TSF_CURRENT_IN_CAP_STATE;
		return HDD_TSF_OP_SUCC;
	}

	/* record adapter for cap_tsf_irq_handler  */
	hddctx->cap_tsf_context = adapter;

	hddLog(VOS_TRACE_LEVEL_INFO, FL("+ioctl issue cap tsf cmd"));

	/* Reset TSF value for new capture */
	adapter->cur_target_time = 0;

	buf[0] = TSF_RETURN;
	ret = process_wma_set_command((int)adapter->sessionId,
			(int)GEN_PARAM_CAPTURE_TSF,
			adapter->sessionId,
			GEN_CMD);

	if (0 != ret) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("cap tsf fail"));
		buf[0] = TSF_CAPTURE_FAIL;
		hddctx->cap_tsf_context = NULL;
		adf_os_atomic_set(&hddctx->cap_tsf_flag, 0);
		return HDD_TSF_OP_SUCC;
	}
	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("-ioctl return cap tsf cmd"));

	return HDD_TSF_OP_SUCC;
}

static enum hdd_tsf_op_result hdd_indicate_tsf_internal(
	hdd_adapter_t *adapter, uint32_t *buf, int len)
{
	int ret;
	hdd_context_t *hddctx;

	if (adapter == NULL || buf == NULL) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("invalid pointer"));
		return HDD_TSF_OP_FAIL;
	}

	if (len != 3)
		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;
	}

	buf[1] = 0;
	buf[2] = 0;

	if (!hdd_tsf_is_initialized(adapter)) {
		buf[0] = TSF_NOT_READY;
		return HDD_TSF_OP_SUCC;
	}

	buf[0] = hdd_tsf_check_conn_state(adapter);
	if (buf[0] != TSF_RETURN)
		return HDD_TSF_OP_SUCC;

	if (adapter->cur_target_time == 0) {
		hddLog(VOS_TRACE_LEVEL_INFO,
				FL("not getting tsf value"));
		buf[0] = TSF_NOT_RETURNED_BY_FW;
		return HDD_TSF_OP_SUCC;
	} else {
		buf[0] = TSF_RETURN;
		buf[1] = (uint32_t)(adapter->cur_target_time & 0xffffffff);
		buf[2] = (uint32_t)((adapter->cur_target_time >> 32) &
				0xffffffff);

		if (!adf_os_atomic_read(&hddctx->cap_tsf_flag)) {
			hddLog(VOS_TRACE_LEVEL_INFO,
				FL("old: status=%u, tsf_low=%u, tsf_high=%u"),
				buf[0], buf[1], buf[2]);
			return HDD_TSF_OP_SUCC;
		}

		ret = hdd_reset_tsf_gpio(adapter);
		if (0 != ret) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
					FL("reset tsf gpio fail"));
			buf[0] = TSF_RESET_GPIO_FAIL;
			return HDD_TSF_OP_SUCC;
		}
		hddctx->cap_tsf_context = NULL;
		adf_os_atomic_set(&hddctx->cap_tsf_flag, 0);
		hddLog(VOS_TRACE_LEVEL_INFO,
			FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
			buf[0], buf[1], buf[2]);
		return HDD_TSF_OP_SUCC;
	}
}

#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 (100 * NSEC_PER_USEC)
#define MAX_CONTINUOUS_ERROR_CNT 3

/**
 * to distinguish 32-bit overflow case, this inverval should:
 * 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 MAX_UINT64 ((uint64_t)0xffffffffffffffff)
#define MASK_UINT32 0xffffffff
#define CAP_TSF_TIMER_FIX_SEC 1

/**
 * 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)
{
	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;

	/* host time is updated in IRQ context, it's always before target time,
	 * and so no need to update last_host_time at present;
	 * assume the interval of capturing TSF
	 * (WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC) is long enough, host and target
	 * time are updated in pairs, we can return here to avoid requiring
	 * spin lock, and to speed up the IRQ processing.
	 */
	if (host_time > 0) {
		adapter->cur_host_time = host_time;
		return;
	}

	spin_lock_bh(&adapter->host_target_sync_lock);
	if (target_time > 0)
		adapter->cur_target_time = target_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);

		/* TSF-HOST need to be updated in at most
		 * WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC, it couldn't be achieved
		 * if the timer interval is also
		 * WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC, due to processing or
		 * schedule delay. So deduct several seconds from
		 * WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC.
		 * Without this change, hdd_get_hosttime_from_targettime() will
		 * get wrong host time when it's longer than
		 * WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC from last
		 * TSF-HOST update. */
		interval = (WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC -
			    CAP_TSF_TIMER_FIX_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 bool hdd_tsf_is_in_cap(hdd_adapter_t *adapter)
{
	hdd_context_t *hddctx;

	hddctx = WLAN_HDD_GET_CTX(adapter);
	if (!hddctx)
		return false;

	return (adf_os_atomic_read(&hddctx->cap_tsf_flag) > 0);
}

/* define 64bit plus/minus to deal with overflow */
static inline int hdd_64bit_plus(uint64_t x, int64_t y, uint64_t *ret)
{
	if ((y < 0 && (-y) > x) ||
	    (y > 0 && (y > MAX_UINT64 - x))) {
		*ret = 0;
		return -EINVAL;
	}

	*ret = x + y;
	return 0;
}

static inline int hdd_uint64_plus(uint64_t x, uint64_t y, uint64_t *ret)
{
	if (!ret)
		return -EINVAL;

	if (x > (MAX_UINT64 - y)) {
		*ret = 0;
		return -EINVAL;
	}

	*ret = x + y;
	return 0;
}

static inline int hdd_uint64_minus(uint64_t x, uint64_t y, uint64_t *ret)
{
	if (!ret)
		return -EINVAL;

	if (x < y) {
		*ret = 0;
		return -EINVAL;
	}

	*ret = x - y;
	return 0;
}

static inline int32_t hdd_get_hosttime_from_targettime(
	hdd_adapter_t *adapter, uint64_t target_time,
	uint64_t *host_time)
{
	int32_t ret = -EINVAL;
	int64_t delta32_target;
	bool in_cap_state;
	int64_t normal_interval_target_value;

	in_cap_state = hdd_tsf_is_in_cap(adapter);

	/*
	 * To avoid check the lock when it's not capturing tsf
	 * (the tstamp-pair won't be changed)
	 */
	if (in_cap_state)
		spin_lock_bh(&adapter->host_target_sync_lock);

	/* at present, target_time is only 32bit in fact */
	delta32_target = (int64_t)((target_time & MASK_UINT32) -
			(adapter->last_target_time & MASK_UINT32));

	normal_interval_target_value =
		 (int64_t)WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC  * NSEC_PER_SEC;
	do_div(normal_interval_target_value, HOST_TO_TARGET_TIME_RATIO);

	if (delta32_target <
			(normal_interval_target_value - OVERFLOW_INDICATOR32))
		delta32_target += OVERFLOW_INDICATOR32;
	else if (delta32_target >
			(OVERFLOW_INDICATOR32 - normal_interval_target_value))
		delta32_target -= OVERFLOW_INDICATOR32;

	ret = hdd_64bit_plus(adapter->last_host_time,
			     HOST_TO_TARGET_TIME_RATIO * delta32_target,
			     host_time);

	if (in_cap_state)
		spin_unlock_bh(&adapter->host_target_sync_lock);

	return ret;
}

static inline int32_t hdd_get_targettime_from_hosttime(
	hdd_adapter_t *adapter, uint64_t host_time,
	uint64_t *target_time)
{
	int32_t ret = -EINVAL;
	bool in_cap_state;

	if (!adapter || host_time == 0)
		return ret;

	in_cap_state = hdd_tsf_is_in_cap(adapter);
	if (in_cap_state)
		spin_lock_bh(&adapter->host_target_sync_lock);

	if (host_time < adapter->last_host_time)
		ret = hdd_uint64_minus(adapter->last_target_time,
				       vos_do_div(adapter->last_host_time -
						  host_time,
						  HOST_TO_TARGET_TIME_RATIO),
				       target_time);
	else
		ret = hdd_uint64_plus(adapter->last_target_time,
				      vos_do_div(host_time -
						 adapter->last_host_time,
						 HOST_TO_TARGET_TIME_RATIO),
				      target_time);

	if (in_cap_state)
		spin_unlock_bh(&adapter->host_target_sync_lock);

	return ret;
}

static inline uint64_t hdd_get_monotonic_host_time(hdd_context_t *hdd_ctx)
{
	return (HDD_TSF_IS_RAW_SET(hdd_ctx) ?
		ktime_get_ns() : ktime_get_real_ns());
}

static ssize_t __hdd_wlan_tsf_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	hdd_station_ctx_t *hdd_sta_ctx;
	hdd_adapter_t *adapter;
	hdd_context_t *hdd_ctx;
	ssize_t size;
	uint64_t host_time, target_time;

	struct net_device *net_dev = container_of(dev, struct net_device, dev);

	adapter = (hdd_adapter_t *)(netdev_priv(net_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_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	if (eConnectionState_Associated != hdd_sta_ctx->conn_info.connState)
		return scnprintf(buf, PAGE_SIZE, "NOT connected\n");

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	if (!hdd_ctx)
		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");
	else
		size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n",
				 buf, target_time, host_time,
				 hdd_sta_ctx->conn_info.bssId);
	return size;
}

static ssize_t hdd_wlan_tsf_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	ssize_t ret;

	vos_ssr_protect(__func__);
	ret = __hdd_wlan_tsf_show(dev, attr, buf);
	vos_ssr_unprotect(__func__);

	return ret;
}

static DEVICE_ATTR(tsf, 0400, hdd_wlan_tsf_show, NULL);

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;

	hdd_ctx = (hdd_context_t *)arg;
	host_time = hdd_get_monotonic_host_time(hdd_ctx);

	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;
	struct net_device *net_dev;

	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;
	}

	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;
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;
	struct net_device *net_dev;

	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);

	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;
}

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);
}

static inline
enum hdd_tsf_op_result hdd_netbuf_timestamp(adf_nbuf_t netbuf,
					    uint64_t target_time)
{
	hdd_adapter_t *adapter;
	struct net_device *net_dev = netbuf->dev;

	if (!net_dev)
		return HDD_TSF_OP_FAIL;

	adapter = (hdd_adapter_t *)(netdev_priv(net_dev));
	if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC &&
	    hdd_get_th_sync_status(adapter)) {
		uint64_t host_time;
		int32_t ret = hdd_get_hosttime_from_targettime(adapter,
				target_time, &host_time);
		if (!ret) {
			netbuf->tstamp = ns_to_ktime(host_time);
			return HDD_TSF_OP_SUCC;
		}
	}

	return HDD_TSF_OP_FAIL;
}

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_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;
}

int hdd_tx_timestamp(adf_nbuf_t netbuf, uint64_t target_time)
{
	struct sock *sk = NULL;

	if (netbuf->sk != NULL)
		sk = netbuf->sk;
	else
		memcpy((void *)(&sk), (void *)(&netbuf->tstamp.tv64),
		       sizeof(sk));

	if (!sk)
		return -EINVAL;

	if ((skb_shinfo(netbuf)->tx_flags & SKBTX_SW_TSTAMP) &&
	    !(skb_shinfo(netbuf)->tx_flags & SKBTX_IN_PROGRESS)) {
		struct sock_exterr_skb *serr;
		adf_nbuf_t new_netbuf;
		int err;

		if (hdd_netbuf_timestamp(netbuf, target_time) !=
		    HDD_TSF_OP_SUCC)
			return -EINVAL;

		new_netbuf = adf_nbuf_clone(netbuf);
		if (!new_netbuf)
			return -ENOMEM;

		serr = SKB_EXT_ERR(new_netbuf);
		memset(serr, 0, sizeof(*serr));
		serr->ee.ee_errno = ENOMSG;
		serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;

		err = sock_queue_err_skb(sk, new_netbuf);
		if (err) {
			adf_nbuf_free(new_netbuf);
			return err;
		}

		return 0;
	}
	return -EINVAL;
}

int hdd_rx_timestamp(adf_nbuf_t netbuf, uint64_t target_time)
{
	if (hdd_netbuf_timestamp(netbuf, target_time) ==
		HDD_TSF_OP_SUCC)
		return 0;

	/* reset tstamp when failed */
	netbuf->tstamp = ns_to_ktime(0);
	return -EINVAL;
}

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;

	if (!HDD_TSF_IS_PTP_ENABLED(hdd_ctx)) {
		hddLog(VOS_TRACE_LEVEL_INFO,
		       FL("To enable TSF_PLUS, set gtsf_ptp_options in ini"));
		return HDD_TSF_OP_FAIL;
	}

	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;
	}

	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(hdd_context_t *hdd_ctx)
{
	int ret;

	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();

	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);
}

void
hdd_tsf_record_sk_for_skb(hdd_context_t *hdd_ctx, adf_nbuf_t nbuf)
{
	/* if TSF_TX is enabled, skb->sk is required when timestamping
	 * the tx skb; at the same time, skb->tstamp is useless at this
	 * point in such case, so record sk in tstamp, in case it will
	 * be set to NULL in skb_orphan().
	 */
	if (HDD_TSF_IS_TX_SET(hdd_ctx))
		memcpy((void *)(&nbuf->tstamp.tv64), (void *)(&nbuf->sk),
		       sizeof(nbuf->sk));
}
#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
 *
 * @pcb_cxt: pointer to the hdd_contex
 * @ptsf: pointer to struct stsf
 *
 * This function handle the event that reported by firmware at first.
 * The event contains the vdev_id, current tsf value of this vdev,
 * tsf value is 64bits, discripted in two varaible tsf_low and tsf_high.
 * These two values each is uint32.
 *
 * Return: Describe the execute result of this routine
 */
static int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
{
	hdd_context_t *hddctx;
	hdd_adapter_t *adapter;
	int status;

	if (pcb_cxt == NULL || ptsf == NULL) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			FL("HDD context is not valid"));
			return -EINVAL;
	}

	hddctx = (hdd_context_t *)pcb_cxt;
	status = wlan_hdd_validate_context(hddctx);
	if (0 != status)
		return -EINVAL;

	adapter = hdd_get_adapter_by_vdev(hddctx, ptsf->vdev_id);

	if (NULL == adapter) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			FL("failed to find adapter"));
		return -EINVAL;
	}

	if (!hdd_tsf_is_initialized(adapter)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			FL("tsf is not init, ignore tsf event"));
		return -EINVAL;
	}

	hddLog(VOS_TRACE_LEVEL_INFO,
		FL("tsf cb handle event, device_mode is %d"),
		adapter->device_mode);

	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);
	return 0;
}

void wlan_hdd_tsf_init(hdd_context_t *hdd_ctx)
{
	eHalStatus hal_status;

	if (!hdd_ctx)
		return;

	if (adf_os_atomic_inc_return(&hdd_ctx->tsf_ready_flag) > 1)
		return;

	adf_os_atomic_init(&hdd_ctx->cap_tsf_flag);

	if (hdd_ctx->cfg_ini->tsf_gpio_pin == TSF_GPIO_PIN_INVALID)
		goto fail;

	hal_status = sme_set_tsf_gpio(hdd_ctx->hHal,
			hdd_ctx->cfg_ini->tsf_gpio_pin);
	if (eHAL_STATUS_SUCCESS != hal_status) {
		hddLog(LOGE, FL("set tsf GPIO failed, status: %d"),
				hal_status);
		goto fail;
	}

	hal_status = sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb, hdd_ctx);
	if (eHAL_STATUS_SUCCESS != hal_status) {
		hddLog(LOGE, FL("set tsf cb failed, status: %d"),
				hal_status);
		goto fail;
	}

	if (wlan_hdd_tsf_plus_init(hdd_ctx) != HDD_TSF_OP_SUCC)
		goto fail;

	return;

fail:
	adf_os_atomic_set(&hdd_ctx->tsf_ready_flag, 0);
	return;
}

void wlan_hdd_tsf_deinit(hdd_context_t *hdd_ctx)
{
	eHalStatus hal_status;

	if (!hdd_ctx)
		return;

	if (!adf_os_atomic_read(&hdd_ctx->tsf_ready_flag))
		return;

	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);
	}

	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);
}
