/*
 * Broadcom Dongle Host Driver (DHD), RTT
 *
 * Copyright (C) 1999-2018, Broadcom.
 *
 *      Unless you and Broadcom execute a separate written software license
 * agreement governing use of this software, this software is licensed to you
 * under the terms of the GNU General Public License version 2 (the "GPL"),
 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
 * following added to such license:
 *
 *      As a special exception, the copyright holders of this software give you
 * permission to link this software with independent modules, and to copy and
 * distribute the resulting executable under terms of your choice, provided that
 * you also meet, for each linked independent module, the terms and conditions of
 * the license of that module.  An independent module is a module which is not
 * derived from this software.  The special exception does not apply to any
 * modifications of the software.
 *
 *      Notwithstanding the above, under no circumstances may you combine this
 * software in any way with any other Broadcom software provided under a license
 * other than the GPL, without Broadcom's express prior written consent.
 *
 * $Id: dhd_rtt.c 606280 2015-12-15 05:28:25Z $
 */
#include <typedefs.h>
#include <osl.h>

#include <epivers.h>
#include <bcmutils.h>

#include <bcmendian.h>
#include <linuxver.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/sort.h>
#include <dngl_stats.h>
#include <wlioctl.h>

#include <proto/bcmevent.h>
#include <dhd.h>
#include <dhd_rtt.h>
#include <dhd_dbg.h>
#include <wldev_common.h>
#ifdef WL_CFG80211_V1
#include <wl_cfg80211_v1.h>
#else
#include <wl_cfg80211.h>
#endif /* WL_CFG80211_V1 */
static DEFINE_SPINLOCK(noti_list_lock);
#define NULL_CHECK(p, s, err)  \
			do { \
				if (!(p)) { \
					printf("NULL POINTER (%s) : %s\n", __FUNCTION__, (s)); \
					err = BCME_ERROR; \
					return err; \
				} \
			} while (0)

#define RTT_IS_ENABLED(rtt_status) (rtt_status->status == RTT_ENABLED)
#define RTT_IS_STOPPED(rtt_status) (rtt_status->status == RTT_STOPPED)
#define TIMESPEC_TO_US(ts)  (((uint64)(ts).tv_sec * USEC_PER_SEC) + \
							(ts).tv_nsec / NSEC_PER_USEC)

#define FTM_IOC_BUFSZ		2048	/* ioc buffsize for our module (> BCM_XTLV_HDR_SIZE) */
#define FTM_AVAIL_MAX_SLOTS	32
#define FTM_MAX_CONFIGS		10
#define FTM_MAX_PARAMS		10
#define FTM_DEFAULT_SESSION	1
#define FTM_BURST_TIMEOUT_UNIT	250 /* 250 ns */
#define FTM_INVALID		-1
#define FTM_DEFAULT_CNT_20M	12
#define FTM_DEFAULT_CNT_40M	10
#define FTM_DEFAULT_CNT_80M	5

/* convenience macros */
#define FTM_TU2MICRO(_tu) ((uint64)(_tu) << 10)
#define FTM_MICRO2TU(_tu) ((uint64)(_tu) >> 10)
#define FTM_TU2MILLI(_tu) ((uint32)FTM_TU2MICRO(_tu) / 1000)
#define FTM_MICRO2MILLI(_x) ((uint32)(_x) / 1000)
#define FTM_MICRO2SEC(_x) ((uint32)(_x) / 1000000)
#define FTM_INTVL2NSEC(_intvl) ((uint32)ftm_intvl2nsec(_intvl))
#define FTM_INTVL2USEC(_intvl) ((uint32)ftm_intvl2usec(_intvl))
#define FTM_INTVL2MSEC(_intvl) (FTM_INTVL2USEC(_intvl) / 1000)
#define FTM_INTVL2SEC(_intvl) (FTM_INTVL2USEC(_intvl) / 1000000)
#define FTM_USECIN100MILLI(_usec) ((_usec) / 100000)

/* broadcom specific set to have more accurate data */
#define ENABLE_VHT_ACK
#define CH_MIN_5G_CHANNEL 34
#define CH_MIN_2G_CHANNEL 1

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
#define ieee80211_band nl80211_band
#define IEEE80211_BAND_2GHZ NL80211_BAND_2GHZ
#define IEEE80211_BAND_5GHZ NL80211_BAND_5GHZ
#define IEEE80211_NUM_BANDS NUM_NL80211_BANDS
#endif

struct rtt_noti_callback {
	struct list_head list;
	void *ctx;
	dhd_rtt_compl_noti_fn noti_fn;
};

/* bitmask indicating which command groups; */
typedef enum {
	FTM_SUBCMD_FLAG_METHOD  = 0x01,	/* FTM method command */
	FTM_SUBCMD_FLAG_SESSION = 0x02,	/* FTM session command */
	FTM_SUBCMD_FLAG_ALL = FTM_SUBCMD_FLAG_METHOD | FTM_SUBCMD_FLAG_SESSION
} ftm_subcmd_flag_t;

/* proxd ftm config-category definition */
typedef enum {
	FTM_CONFIG_CAT_GENERAL = 1,	/* generial configuration */
	FTM_CONFIG_CAT_OPTIONS = 2,	/* 'config options' */
	FTM_CONFIG_CAT_AVAIL = 3,	/* 'config avail' */
} ftm_config_category_t;

typedef struct ftm_subcmd_info {
	int16			version;	/* FTM version (optional) */
	char			*name;		/* cmd-name string as cmdline input */
	wl_proxd_cmd_t		cmdid;		/* cmd-id */
	bcm_xtlv_unpack_cbfn_t	*handler;	/* cmd response handler (optional) */
	ftm_subcmd_flag_t	cmdflag;	/* CMD flag (optional)  */
} ftm_subcmd_info_t;

typedef struct ftm_config_options_info {
	uint32 flags;				/* wl_proxd_flags_t/wl_proxd_session_flags_t */
	bool enable;
} ftm_config_options_info_t;

typedef struct ftm_config_param_info {
	uint16		tlvid;	/* mapping TLV id for the item */
	union {
		uint32  chanspec;
		struct ether_addr mac_addr;
		wl_proxd_intvl_t data_intvl;
		uint32 data32;
		uint16 data16;
		uint8 data8;
	};
} ftm_config_param_info_t;

/*
* definition for id-string mapping.
*   This is used to map an id (can be cmd-id, tlv-id, ....) to a text-string
*   for debug-display or cmd-log-display
*/
typedef struct ftm_strmap_entry {
	int32		id;
	char		*text;
} ftm_strmap_entry_t;

typedef struct ftm_status_map_host_entry {
	wl_proxd_status_t proxd_status;
	rtt_reason_t rtt_reason;
} ftm_status_map_host_entry_t;

static int
dhd_rtt_convert_results_to_host(rtt_report_t *rtt_report, uint8 *p_data, uint16 tlvid, uint16 len);

static wifi_rate_t
dhd_rtt_convert_rate_to_host(uint32 ratespec);

static int
dhd_rtt_start(dhd_pub_t *dhd);
static const int burst_duration_idx[]  = {0, 0, 1, 2, 4, 8, 16, 32, 64, 128, 0, 0};

/* ftm status mapping to host status */
static const ftm_status_map_host_entry_t ftm_status_map_info[] = {
	{WL_PROXD_E_INCOMPLETE, RTT_REASON_FAILURE},
	{WL_PROXD_E_OVERRIDDEN, RTT_REASON_FAILURE},
	{WL_PROXD_E_ASAP_FAILED, RTT_REASON_FAILURE},
	{WL_PROXD_E_NOTSTARTED, RTT_REASON_FAIL_NOT_SCHEDULED_YET},
	{WL_PROXD_E_INVALIDAVB, RTT_REASON_FAIL_INVALID_TS},
	{WL_PROXD_E_INCAPABLE, RTT_REASON_FAIL_NO_CAPABILITY},
	{WL_PROXD_E_MISMATCH, RTT_REASON_FAILURE},
	{WL_PROXD_E_DUP_SESSION, RTT_REASON_FAILURE},
	{WL_PROXD_E_REMOTE_FAIL, RTT_REASON_FAILURE},
	{WL_PROXD_E_REMOTE_INCAPABLE, RTT_REASON_FAILURE},
	{WL_PROXD_E_SCHED_FAIL, RTT_REASON_FAIL_SCHEDULE},
	{WL_PROXD_E_PROTO, RTT_REASON_FAIL_PROTOCOL},
	{WL_PROXD_E_EXPIRED, RTT_REASON_FAILURE},
	{WL_PROXD_E_TIMEOUT, RTT_REASON_FAIL_TM_TIMEOUT},
	{WL_PROXD_E_NOACK, RTT_REASON_FAIL_NO_RSP},
	{WL_PROXD_E_DEFERRED, RTT_REASON_FAILURE},
	{WL_PROXD_E_INVALID_SID, RTT_REASON_FAILURE},
	{WL_PROXD_E_REMOTE_CANCEL, RTT_REASON_FAILURE},
	{WL_PROXD_E_CANCELED, RTT_REASON_ABORTED},
	{WL_PROXD_E_INVALID_SESSION, RTT_REASON_FAILURE},
	{WL_PROXD_E_BAD_STATE, RTT_REASON_FAILURE},
	{WL_PROXD_E_ERROR, RTT_REASON_FAILURE},
	{WL_PROXD_E_OK, RTT_REASON_SUCCESS}
};

/* for using clang compiler,
 * error: unused variable 'ftm_tlvid_loginfo'
 * [-Werror,-Wunused-const-variable]
 */
#if 0
/* ftm tlv-id mapping */
static const ftm_strmap_entry_t ftm_tlvid_loginfo[] = {
	/* { WL_PROXD_TLV_ID_xxx,		"text for WL_PROXD_TLV_ID_xxx" }, */
	{ WL_PROXD_TLV_ID_NONE,			"none" },
	{ WL_PROXD_TLV_ID_METHOD,		"method" },
	{ WL_PROXD_TLV_ID_FLAGS,		"flags" },
	{ WL_PROXD_TLV_ID_CHANSPEC,		"chanspec" },
	{ WL_PROXD_TLV_ID_TX_POWER,		"tx power" },
	{ WL_PROXD_TLV_ID_RATESPEC,		"ratespec" },
	{ WL_PROXD_TLV_ID_BURST_DURATION,	"burst duration" },
	{ WL_PROXD_TLV_ID_BURST_PERIOD,		"burst period" },
	{ WL_PROXD_TLV_ID_BURST_FTM_SEP,	"burst ftm sep" },
	{ WL_PROXD_TLV_ID_BURST_NUM_FTM,	"burst num ftm" },
	{ WL_PROXD_TLV_ID_NUM_BURST,		"num burst" },
	{ WL_PROXD_TLV_ID_FTM_RETRIES,		"ftm retries" },
	{ WL_PROXD_TLV_ID_BSS_INDEX,		"BSS index" },
	{ WL_PROXD_TLV_ID_BSSID,		"bssid" },
	{ WL_PROXD_TLV_ID_INIT_DELAY,		"burst init delay" },
	{ WL_PROXD_TLV_ID_BURST_TIMEOUT,	"burst timeout" },
	{ WL_PROXD_TLV_ID_EVENT_MASK,		"event mask" },
	{ WL_PROXD_TLV_ID_FLAGS_MASK,		"flags mask" },
	{ WL_PROXD_TLV_ID_PEER_MAC,		"peer addr" },
	{ WL_PROXD_TLV_ID_FTM_REQ,		"ftm req" },
	{ WL_PROXD_TLV_ID_LCI_REQ,		"lci req" },
	{ WL_PROXD_TLV_ID_LCI,			"lci" },
	{ WL_PROXD_TLV_ID_CIVIC_REQ,		"civic req" },
	{ WL_PROXD_TLV_ID_CIVIC,		"civic" },
	{ WL_PROXD_TLV_ID_AVAIL,		"availability" },
	{ WL_PROXD_TLV_ID_SESSION_FLAGS,	"session flags" },
	{ WL_PROXD_TLV_ID_SESSION_FLAGS_MASK,	"session flags mask" },
	{ WL_PROXD_TLV_ID_RX_MAX_BURST,		"rx max bursts" },
	{ WL_PROXD_TLV_ID_RANGING_INFO,		"ranging info" },
	{ WL_PROXD_TLV_ID_RANGING_FLAGS,	"ranging flags" },
	{ WL_PROXD_TLV_ID_RANGING_FLAGS_MASK,	"ranging flags mask" },
	/* output - 512 + x */
	{ WL_PROXD_TLV_ID_STATUS,		"status" },
	{ WL_PROXD_TLV_ID_COUNTERS,		"counters" },
	{ WL_PROXD_TLV_ID_INFO,			"info" },
	{ WL_PROXD_TLV_ID_RTT_RESULT,		"rtt result" },
	{ WL_PROXD_TLV_ID_AOA_RESULT,		"aoa result" },
	{ WL_PROXD_TLV_ID_SESSION_INFO,		"session info" },
	{ WL_PROXD_TLV_ID_SESSION_STATUS,	"session status" },
	{ WL_PROXD_TLV_ID_SESSION_ID_LIST,	"session ids" },
	/* debug tlvs can be added starting 1024 */
	{ WL_PROXD_TLV_ID_DEBUG_MASK,		"debug mask" },
	{ WL_PROXD_TLV_ID_COLLECT,		"collect" },
	{ WL_PROXD_TLV_ID_STRBUF,				"result" }
};
#endif

static const ftm_strmap_entry_t ftm_event_type_loginfo[] = {
	/* wl_proxd_event_type_t,		text-string */
	{ WL_PROXD_EVENT_NONE,			"none" },
	{ WL_PROXD_EVENT_SESSION_CREATE,	"session create" },
	{ WL_PROXD_EVENT_SESSION_START,		"session start" },
	{ WL_PROXD_EVENT_FTM_REQ,		"FTM req" },
	{ WL_PROXD_EVENT_BURST_START,		"burst start" },
	{ WL_PROXD_EVENT_BURST_END,		"burst end" },
	{ WL_PROXD_EVENT_SESSION_END,		"session end" },
	{ WL_PROXD_EVENT_SESSION_RESTART,	"session restart" },
	{ WL_PROXD_EVENT_BURST_RESCHED,		"burst rescheduled" },
	{ WL_PROXD_EVENT_SESSION_DESTROY,	"session destroy" },
	{ WL_PROXD_EVENT_RANGE_REQ,		"range request" },
	{ WL_PROXD_EVENT_FTM_FRAME,		"FTM frame" },
	{ WL_PROXD_EVENT_DELAY,			"delay" },
	{ WL_PROXD_EVENT_VS_INITIATOR_RPT,	"initiator-report " }, /* rx initiator-rpt */
	{ WL_PROXD_EVENT_RANGING,		"ranging " },
};

/*
* session-state --> text string mapping
*/
static const ftm_strmap_entry_t ftm_session_state_value_loginfo[] = {
	/* wl_proxd_session_state_t,		text string */
	{ WL_PROXD_SESSION_STATE_CREATED,	"created" },
	{ WL_PROXD_SESSION_STATE_CONFIGURED,	"configured" },
	{ WL_PROXD_SESSION_STATE_STARTED,	"started" },
	{ WL_PROXD_SESSION_STATE_DELAY,		"delay" },
	{ WL_PROXD_SESSION_STATE_USER_WAIT,	"user-wait" },
	{ WL_PROXD_SESSION_STATE_SCHED_WAIT,	"sched-wait" },
	{ WL_PROXD_SESSION_STATE_BURST,		"burst" },
	{ WL_PROXD_SESSION_STATE_STOPPING,	"stopping" },
	{ WL_PROXD_SESSION_STATE_ENDED,		"ended" },
	{ WL_PROXD_SESSION_STATE_DESTROYING,	"destroying" },
	{ WL_PROXD_SESSION_STATE_NONE,		"none" }
};

/* for using clang compiler
 * error: unused variable 'ftm_ranging_state_value_loginfo'
 * [-Werror,-Wunused-const-variable]
 */
#if 0
/*
* ranging-state --> text string mapping
*/
static const ftm_strmap_entry_t ftm_ranging_state_value_loginfo [] = {
	/* wl_proxd_ranging_state_t,		text string */
	{ WL_PROXD_RANGING_STATE_NONE,		"none" },
	{ WL_PROXD_RANGING_STATE_NOTSTARTED,	"nonstarted" },
	{ WL_PROXD_RANGING_STATE_INPROGRESS,	"inprogress" },
	{ WL_PROXD_RANGING_STATE_DONE,		"done" },
};
#endif

/*
* status --> text string mapping
*/
static const ftm_strmap_entry_t ftm_status_value_loginfo[] = {
	/* wl_proxd_status_t,			text-string */
	{ WL_PROXD_E_OVERRIDDEN,		"overridden" },
	{ WL_PROXD_E_ASAP_FAILED,		"ASAP failed" },
	{ WL_PROXD_E_NOTSTARTED,		"not started" },
	{ WL_PROXD_E_INVALIDAVB,		"invalid AVB" },
	{ WL_PROXD_E_INCAPABLE,			"incapable" },
	{ WL_PROXD_E_MISMATCH,			"mismatch"},
	{ WL_PROXD_E_DUP_SESSION,		"dup session" },
	{ WL_PROXD_E_REMOTE_FAIL,		"remote fail" },
	{ WL_PROXD_E_REMOTE_INCAPABLE,		"remote incapable" },
	{ WL_PROXD_E_SCHED_FAIL,		"sched failure" },
	{ WL_PROXD_E_PROTO,			"protocol error" },
	{ WL_PROXD_E_EXPIRED,			"expired" },
	{ WL_PROXD_E_TIMEOUT,			"timeout" },
	{ WL_PROXD_E_NOACK,			"no ack" },
	{ WL_PROXD_E_DEFERRED,			"deferred" },
	{ WL_PROXD_E_INVALID_SID,		"invalid session id" },
	{ WL_PROXD_E_REMOTE_CANCEL,		"remote cancel" },
	{ WL_PROXD_E_CANCELED,			"canceled" },
	{ WL_PROXD_E_INVALID_SESSION,		"invalid session" },
	{ WL_PROXD_E_BAD_STATE,			"bad state" },
	{ WL_PROXD_E_ERROR,			"error" },
	{ WL_PROXD_E_OK,			"OK" }
};

/*
* time interval unit --> text string mapping
*/
static const ftm_strmap_entry_t ftm_tmu_value_loginfo[] = {
	/* wl_proxd_tmu_t,		text-string */
	{ WL_PROXD_TMU_TU,		"TU" },
	{ WL_PROXD_TMU_SEC,		"sec" },
	{ WL_PROXD_TMU_MILLI_SEC,	"ms" },
	{ WL_PROXD_TMU_MICRO_SEC,	"us" },
	{ WL_PROXD_TMU_NANO_SEC,	"ns" },
	{ WL_PROXD_TMU_PICO_SEC,	"ps" }
};

#define RSPEC_BW(rspec)         ((rspec) & WL_RSPEC_BW_MASK)
#define RSPEC_IS20MHZ(rspec)	(RSPEC_BW(rspec) == WL_RSPEC_BW_20MHZ)
#define RSPEC_IS40MHZ(rspec)	(RSPEC_BW(rspec) == WL_RSPEC_BW_40MHZ)
#define RSPEC_IS80MHZ(rspec)    (RSPEC_BW(rspec) == WL_RSPEC_BW_80MHZ)
#define RSPEC_IS160MHZ(rspec)   (RSPEC_BW(rspec) == WL_RSPEC_BW_160MHZ)

#define IS_MCS(rspec)     	(((rspec) & WL_RSPEC_ENCODING_MASK) != WL_RSPEC_ENCODE_RATE)
#define IS_STBC(rspec)     	(((((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_HT) ||	\
	(((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_VHT)) &&	\
	(((rspec) & WL_RSPEC_STBC) == WL_RSPEC_STBC))
#define RSPEC_ISSGI(rspec)      (((rspec) & WL_RSPEC_SGI) != 0)
#define RSPEC_ISLDPC(rspec)     (((rspec) & WL_RSPEC_LDPC) != 0)
#define RSPEC_ISSTBC(rspec)     (((rspec) & WL_RSPEC_STBC) != 0)
#define RSPEC_ISTXBF(rspec)     (((rspec) & WL_RSPEC_TXBF) != 0)
#define RSPEC_ISVHT(rspec)    	(((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_VHT)
#define RSPEC_ISHT(rspec)	(((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_HT)
#define RSPEC_ISLEGACY(rspec)   (((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_RATE)
#define RSPEC2RATE(rspec)	(RSPEC_ISLEGACY(rspec) ? \
				 ((rspec) & RSPEC_RATE_MASK) : rate_rspec2rate(rspec))
/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */
#define RSPEC2KBPS(rspec)	rate_rspec2rate(rspec)

struct ieee_80211_mcs_rate_info {
	uint8 constellation_bits;
	uint8 coding_q;
	uint8 coding_d;
};

static const struct ieee_80211_mcs_rate_info wl_mcs_info[] = {
	{ 1, 1, 2 }, /* MCS  0: MOD: BPSK,   CR 1/2 */
	{ 2, 1, 2 }, /* MCS  1: MOD: QPSK,   CR 1/2 */
	{ 2, 3, 4 }, /* MCS  2: MOD: QPSK,   CR 3/4 */
	{ 4, 1, 2 }, /* MCS  3: MOD: 16QAM,  CR 1/2 */
	{ 4, 3, 4 }, /* MCS  4: MOD: 16QAM,  CR 3/4 */
	{ 6, 2, 3 }, /* MCS  5: MOD: 64QAM,  CR 2/3 */
	{ 6, 3, 4 }, /* MCS  6: MOD: 64QAM,  CR 3/4 */
	{ 6, 5, 6 }, /* MCS  7: MOD: 64QAM,  CR 5/6 */
	{ 8, 3, 4 }, /* MCS  8: MOD: 256QAM, CR 3/4 */
	{ 8, 5, 6 }  /* MCS  9: MOD: 256QAM, CR 5/6 */
};

/**
 * Returns the rate in [Kbps] units for a caller supplied MCS/bandwidth/Nss/Sgi combination.
 *     'mcs' : a *single* spatial stream MCS (11n or 11ac)
 */
uint
rate_mcs2rate(uint mcs, uint nss, uint bw, int sgi)
{
	const int ksps = 250; /* kilo symbols per sec, 4 us sym */
	const int Nsd_20MHz = 52;
	const int Nsd_40MHz = 108;
	const int Nsd_80MHz = 234;
	const int Nsd_160MHz = 468;
	uint rate;

	if (mcs == 32) {
		/* just return fixed values for mcs32 instead of trying to parametrize */
		rate = (sgi == 0) ? 6000 : 6778;
	} else if (mcs <= 9) {
		/* This calculation works for 11n HT and 11ac VHT if the HT mcs values
		 * are decomposed into a base MCS = MCS % 8, and Nss = 1 + MCS / 8.
		 * That is, HT MCS 23 is a base MCS = 7, Nss = 3
		 */

		/* find the number of complex numbers per symbol */
		if (RSPEC_IS20MHZ(bw)) {
			rate = Nsd_20MHz;
		} else if (RSPEC_IS40MHZ(bw)) {
			rate = Nsd_40MHz;
		} else if (bw == WL_RSPEC_BW_80MHZ) {
			rate = Nsd_80MHz;
		} else if (bw == WL_RSPEC_BW_160MHZ) {
			rate = Nsd_160MHz;
		} else {
			rate = 0;
		}

		/* multiply by bits per number from the constellation in use */
		rate = rate * wl_mcs_info[mcs].constellation_bits;

		/* adjust for the number of spatial streams */
		rate = rate * nss;

		/* adjust for the coding rate given as a quotient and divisor */
		rate = (rate * wl_mcs_info[mcs].coding_q) / wl_mcs_info[mcs].coding_d;

		/* multiply by Kilo symbols per sec to get Kbps */
		rate = rate * ksps;

		/* adjust the symbols per sec for SGI
		 * symbol duration is 4 us without SGI, and 3.6 us with SGI,
		 * so ratio is 10 / 9
		 */
		if (sgi) {
			/* add 4 for rounding of division by 9 */
			rate = ((rate * 10) + 4) / 9;
		}
	} else {
		rate = 0;
	}

	return rate;
} /* wlc_rate_mcs2rate */

/** take a well formed ratespec_t arg and return phy rate in [Kbps] units */
static uint32
rate_rspec2rate(uint32 rspec)
{
	int rate = 0;

	if (RSPEC_ISLEGACY(rspec)) {
		rate = 500 * (rspec & WL_RSPEC_RATE_MASK);
	} else if (RSPEC_ISHT(rspec)) {
		uint mcs = (rspec & WL_RSPEC_RATE_MASK);

		if (mcs == 32) {
			rate = rate_mcs2rate(mcs, 1, WL_RSPEC_BW_40MHZ, RSPEC_ISSGI(rspec));
		} else {
			uint nss = 1 + (mcs / 8);
			mcs = mcs % 8;
			rate = rate_mcs2rate(mcs, nss, RSPEC_BW(rspec), RSPEC_ISSGI(rspec));
		}
	} else if (RSPEC_ISVHT(rspec)) {
		uint mcs = (rspec & WL_RSPEC_VHT_MCS_MASK);
		uint nss = (rspec & WL_RSPEC_VHT_NSS_MASK) >> WL_RSPEC_VHT_NSS_SHIFT;
		if (mcs > 9 || nss > 8) {
			DHD_RTT(("%s: Invalid mcs %d or nss %d\n", __FUNCTION__, mcs, nss));
			goto exit;
		}

		rate = rate_mcs2rate(mcs, nss, RSPEC_BW(rspec), RSPEC_ISSGI(rspec));
	} else {
		DHD_RTT(("%s: wrong rspec:%d\n", __FUNCTION__, rspec));
	}
exit:
	return rate;
}

char resp_buf[WLC_IOCTL_SMLEN];

static uint64
ftm_intvl2nsec(const wl_proxd_intvl_t *intvl)
{
	uint64 ret;
	ret = intvl->intvl;
	switch (intvl->tmu) {
	case WL_PROXD_TMU_TU:			ret = FTM_TU2MICRO(ret) * 1000; break;
	case WL_PROXD_TMU_SEC:			ret *= 1000000000; break;
	case WL_PROXD_TMU_MILLI_SEC:	ret *= 1000000; break;
	case WL_PROXD_TMU_MICRO_SEC:	ret *= 1000; break;
	case WL_PROXD_TMU_PICO_SEC:		ret = intvl->intvl / 1000; break;
	case WL_PROXD_TMU_NANO_SEC:		/* fall through */
	default:						break;
	}
	return ret;
}
uint64
ftm_intvl2usec(const wl_proxd_intvl_t *intvl)
{
	uint64 ret;
	ret = intvl->intvl;
	switch (intvl->tmu) {
	case WL_PROXD_TMU_TU:			ret = FTM_TU2MICRO(ret); break;
	case WL_PROXD_TMU_SEC:			ret *= 1000000; break;
	case WL_PROXD_TMU_NANO_SEC:		ret = intvl->intvl / 1000; break;
	case WL_PROXD_TMU_PICO_SEC:		ret = intvl->intvl / 1000000; break;
	case WL_PROXD_TMU_MILLI_SEC:	ret *= 1000; break;
	case WL_PROXD_TMU_MICRO_SEC:	/* fall through */
	default:						break;
	}
	return ret;
}

/*
* lookup 'id' (as a key) from a fw status to host map table
* if found, return the corresponding reason code
*/

static rtt_reason_t
ftm_get_statusmap_info(wl_proxd_status_t id, const ftm_status_map_host_entry_t *p_table,
	uint32 num_entries)
{
	int i;
	const ftm_status_map_host_entry_t *p_entry;
	/* scan thru the table till end */
	p_entry = p_table;
	for (i = 0; i < (int) num_entries; i++)
	{
		if (p_entry->proxd_status == id) {
			return p_entry->rtt_reason;
		}
		p_entry++;		/* next entry */
	}
	return RTT_REASON_FAILURE; /* not found */
}
/*
* lookup 'id' (as a key) from a table
* if found, return the entry pointer, otherwise return NULL
*/
static const ftm_strmap_entry_t*
ftm_get_strmap_info(int32 id, const ftm_strmap_entry_t *p_table, uint32 num_entries)
{
	int i;
	const ftm_strmap_entry_t *p_entry;

	/* scan thru the table till end */
	p_entry = p_table;
	for (i = 0; i < (int) num_entries; i++)
	{
		if (p_entry->id == id)
			return p_entry;
		p_entry++;		/* next entry */
	}
	return NULL;			/* not found */
}

/*
* map enum to a text-string for display, this function is called by the following:
* For debug/trace:
*     ftm_[cmdid|tlvid]_to_str()
* For TLV-output log for 'get' commands
*     ftm_[method|tmu|caps|status|state]_value_to_logstr()
* Input:
*     pTable -- point to a 'enum to string' table.
*/
static const char *
ftm_map_id_to_str(int32 id, const ftm_strmap_entry_t *p_table, uint32 num_entries)
{
	const ftm_strmap_entry_t*p_entry = ftm_get_strmap_info(id, p_table, num_entries);
	if (p_entry)
		return (p_entry->text);

	return "invalid";
}

#ifdef RTT_DEBUG

/* define entry, e.g. { WL_PROXD_CMD_xxx, "WL_PROXD_CMD_xxx" } */
#define DEF_STRMAP_ENTRY(id) { (id), #id }

/* ftm cmd-id mapping */
static const ftm_strmap_entry_t ftm_cmdid_map[] = {
	/* {wl_proxd_cmd_t(WL_PROXD_CMD_xxx), "WL_PROXD_CMD_xxx" }, */
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_NONE),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_GET_VERSION),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_ENABLE),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_DISABLE),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_CONFIG),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_START_SESSION),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_BURST_REQUEST),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_STOP_SESSION),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_DELETE_SESSION),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_GET_RESULT),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_GET_INFO),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_GET_STATUS),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_GET_SESSIONS),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_GET_COUNTERS),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_CLEAR_COUNTERS),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_COLLECT),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_TUNE),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_DUMP),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_START_RANGING),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_STOP_RANGING),
	DEF_STRMAP_ENTRY(WL_PROXD_CMD_GET_RANGING_INFO),
};

/*
* map a ftm cmd-id to a text-string for display
*/
static const char *
ftm_cmdid_to_str(uint16 cmdid)
{
	return ftm_map_id_to_str((int32) cmdid, &ftm_cmdid_map[0], ARRAYSIZE(ftm_cmdid_map));
}
#endif /* RTT_DEBUG */

/*
* convert BCME_xxx error codes into related error strings
* note, bcmerrorstr() defined in bcmutils is for BCMDRIVER only,
*       this duplicate copy is for WL access and may need to clean up later
*/
static const char *ftm_bcmerrorstrtable[] = BCMERRSTRINGTABLE;
static const char *
ftm_status_value_to_logstr(wl_proxd_status_t status)
{
	static char ftm_msgbuf_status_undef[32];
	const ftm_strmap_entry_t *p_loginfo;
	int bcmerror;

	/* check if within BCME_xxx error range */
	bcmerror = (int) status;
	if (VALID_BCMERROR(bcmerror))
		return ftm_bcmerrorstrtable[-bcmerror];

	/* otherwise, look for 'proxd ftm status' range */
	p_loginfo = ftm_get_strmap_info((int32) status,
		&ftm_status_value_loginfo[0], ARRAYSIZE(ftm_status_value_loginfo));
	if (p_loginfo)
		return p_loginfo->text;

	/* report for 'out of range' FTM-status error code */
	memset(ftm_msgbuf_status_undef, 0, sizeof(ftm_msgbuf_status_undef));
	snprintf(ftm_msgbuf_status_undef, sizeof(ftm_msgbuf_status_undef),
		"Undefined status %d", status);
	return &ftm_msgbuf_status_undef[0];
}

static const char *
ftm_tmu_value_to_logstr(wl_proxd_tmu_t tmu)
{
	return ftm_map_id_to_str((int32)tmu,
		&ftm_tmu_value_loginfo[0], ARRAYSIZE(ftm_tmu_value_loginfo));
}

static const ftm_strmap_entry_t*
ftm_get_event_type_loginfo(wl_proxd_event_type_t	event_type)
{
	/* look up 'event-type' from a predefined table  */
	return ftm_get_strmap_info((int32) event_type,
		ftm_event_type_loginfo, ARRAYSIZE(ftm_event_type_loginfo));
}

static const char *
ftm_session_state_value_to_logstr(wl_proxd_session_state_t state)
{
	return ftm_map_id_to_str((int32)state, &ftm_session_state_value_loginfo[0],
		ARRAYSIZE(ftm_session_state_value_loginfo));
}


/*
* send 'proxd' iovar for all ftm get-related commands
*/
static int
rtt_do_get_ioctl(dhd_pub_t *dhd, wl_proxd_iov_t *p_proxd_iov, uint16 proxd_iovsize,
	ftm_subcmd_info_t *p_subcmd_info)
{

	wl_proxd_iov_t *p_iovresp = (wl_proxd_iov_t *)resp_buf;
	int status;
	int tlvs_len;
	/*  send getbuf proxd iovar */
	status = dhd_getiovar(dhd, 0, "proxd", (char *)p_proxd_iov,
			proxd_iovsize, (char **)&p_iovresp, WLC_IOCTL_SMLEN);
	if (status != BCME_OK) {
		DHD_ERROR(("%s: failed to send getbuf proxd iovar (CMD ID : %d), status=%d\n",
			__FUNCTION__, p_subcmd_info->cmdid, status));
		return status;
	}
	if (p_subcmd_info->cmdid == WL_PROXD_CMD_GET_VERSION) {
		p_subcmd_info->version = ltoh16(p_iovresp->version);
		DHD_RTT(("ftm version: 0x%x\n", ltoh16(p_iovresp->version)));
		goto exit;
	}

	tlvs_len = ltoh16(p_iovresp->len) - WL_PROXD_IOV_HDR_SIZE;
	if (tlvs_len < 0) {
		DHD_ERROR(("%s: alert, p_iovresp->len(%d) should not be smaller than %d\n",
			__FUNCTION__, ltoh16(p_iovresp->len), (int) WL_PROXD_IOV_HDR_SIZE));
		tlvs_len = 0;
	}

	if (tlvs_len > 0 && p_subcmd_info->handler) {
		/* unpack TLVs and invokes the cbfn for processing */
		status = bcm_unpack_xtlv_buf(p_proxd_iov, (uint8 *)p_iovresp->tlvs,
				tlvs_len, BCM_XTLV_OPTION_ALIGN32, p_subcmd_info->handler);
	}
exit:
	return status;
}

static wl_proxd_iov_t *
rtt_alloc_getset_buf(wl_proxd_method_t method, wl_proxd_session_id_t session_id,
	wl_proxd_cmd_t cmdid, uint16 tlvs_bufsize, uint16 *p_out_bufsize)
{
	uint16 proxd_iovsize;
	uint32 kflags;
	wl_proxd_tlv_t *p_tlv;
	wl_proxd_iov_t *p_proxd_iov = (wl_proxd_iov_t *) NULL;

	*p_out_bufsize = 0;	/* init */
	kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
	/* calculate the whole buffer size, including one reserve-tlv entry in the header */
	proxd_iovsize = sizeof(wl_proxd_iov_t) + tlvs_bufsize;

	p_proxd_iov = kzalloc(proxd_iovsize, kflags);
	if (p_proxd_iov == NULL) {
		DHD_ERROR(("error: failed to allocate %d bytes of memory\n", proxd_iovsize));
		return NULL;
	}

	/* setup proxd-FTM-method iovar header */
	p_proxd_iov->version = htol16(WL_PROXD_API_VERSION);
	p_proxd_iov->len = htol16(proxd_iovsize); /* caller may adjust it based on #of TLVs */
	p_proxd_iov->cmd = htol16(cmdid);
	p_proxd_iov->method = htol16(method);
	p_proxd_iov->sid = htol16(session_id);

	/* initialize the reserved/dummy-TLV in iovar header */
	p_tlv = p_proxd_iov->tlvs;
	p_tlv->id = htol16(WL_PROXD_TLV_ID_NONE);
	p_tlv->len = htol16(0);

	*p_out_bufsize = proxd_iovsize;	/* for caller's reference */

	return p_proxd_iov;
}

static int
dhd_rtt_common_get_handler(dhd_pub_t *dhd, ftm_subcmd_info_t *p_subcmd_info,
	wl_proxd_method_t method,
	wl_proxd_session_id_t session_id)
{
	int status = BCME_OK;
	uint16 proxd_iovsize = 0;
	wl_proxd_iov_t *p_proxd_iov;
#ifdef RTT_DEBUG
	DHD_RTT(("enter %s: method=%d, session_id=%d, cmdid=%d(%s)\n",
		__FUNCTION__, method, session_id, p_subcmd_info->cmdid,
		ftm_cmdid_to_str(p_subcmd_info->cmdid)));
#endif
	/* alloc mem for ioctl headr + reserved 0 bufsize for tlvs (initialize to zero) */
	p_proxd_iov = rtt_alloc_getset_buf(method, session_id, p_subcmd_info->cmdid,
		0, &proxd_iovsize);

	if (p_proxd_iov == NULL)
		return BCME_NOMEM;

	status = rtt_do_get_ioctl(dhd, p_proxd_iov, proxd_iovsize, p_subcmd_info);

	if (status != BCME_OK) {
		DHD_RTT(("%s failed: status=%d\n", __FUNCTION__, status));
	}
	kfree(p_proxd_iov);
	return status;
}

/*
* common handler for set-related proxd method commands which require no TLV as input
*   wl proxd ftm [session-id] <set-subcmd>
* e.g.
*   wl proxd ftm enable -- to enable ftm
*   wl proxd ftm disable -- to disable ftm
*   wl proxd ftm <session-id> start -- to start a specified session
*   wl proxd ftm <session-id> stop  -- to cancel a specified session;
*                                    state is maintained till session is delete.
*   wl proxd ftm <session-id> delete -- to delete a specified session
*   wl proxd ftm [<session-id>] clear-counters -- to clear counters
*   wl proxd ftm <session-id> burst-request -- on initiator: to send burst request;
*                                              on target: send FTM frame
*   wl proxd ftm <session-id> collect
*   wl proxd ftm tune     (TBD)
*/
static int
dhd_rtt_common_set_handler(dhd_pub_t *dhd, const ftm_subcmd_info_t *p_subcmd_info,
	wl_proxd_method_t method, wl_proxd_session_id_t session_id)
{
	uint16 proxd_iovsize;
	wl_proxd_iov_t *p_proxd_iov;
	int ret;

#ifdef RTT_DEBUG
	DHD_RTT(("enter %s: method=%d, session_id=%d, cmdid=%d(%s)\n",
		__FUNCTION__, method, session_id, p_subcmd_info->cmdid,
		ftm_cmdid_to_str(p_subcmd_info->cmdid)));
#endif

	/* allocate and initialize a temp buffer for 'set proxd' iovar */
	proxd_iovsize = 0;
	p_proxd_iov = rtt_alloc_getset_buf(method, session_id, p_subcmd_info->cmdid,
		0, &proxd_iovsize);	/* no TLV */
	if (p_proxd_iov == NULL)
		return BCME_NOMEM;

	/* no TLV to pack, simply issue a set-proxd iovar */
	ret = dhd_iovar(dhd, 0, "proxd", (char *)p_proxd_iov, proxd_iovsize, TRUE);
#ifdef RTT_DEBUG
	if (ret != BCME_OK) {
		DHD_RTT(("error: IOVAR failed, status=%d\n", ret));
	}
#endif
	/* clean up */
	kfree(p_proxd_iov);

	return ret;
}

static int
rtt_unpack_xtlv_cbfn(void *ctx, uint8 *p_data, uint16 tlvid, uint16 len)
{
	int ret = BCME_OK;
	wl_proxd_ftm_session_status_t *p_data_info;
	switch (tlvid) {
	case WL_PROXD_TLV_ID_RTT_RESULT:
		ret = dhd_rtt_convert_results_to_host((rtt_report_t *)ctx,
					p_data, tlvid, len);
		break;
	case WL_PROXD_TLV_ID_SESSION_STATUS:
		memcpy(ctx, p_data, sizeof(wl_proxd_ftm_session_status_t));
		p_data_info = (wl_proxd_ftm_session_status_t *)ctx;
		p_data_info->state = ltoh16_ua(&p_data_info->state);
		p_data_info->status = ltoh32_ua(&p_data_info->status);
		break;
	default:
		DHD_ERROR(("> Unsupported TLV ID %d\n", tlvid));
		ret = BCME_ERROR;
		break;
	}

	return ret;
}

static int
rtt_handle_config_options(wl_proxd_session_id_t session_id, wl_proxd_tlv_t **p_tlv,
	uint16 *p_buf_space_left, ftm_config_options_info_t *ftm_configs, int ftm_cfg_cnt)
{
	int ret = BCME_OK;
	int cfg_idx = 0;
	uint32 flags = WL_PROXD_FLAG_NONE;
	uint32 flags_mask = WL_PROXD_FLAG_NONE;
	uint32 new_mask;	/* cmdline input */
	ftm_config_options_info_t *p_option_info;
	uint16 type = (session_id == WL_PROXD_SESSION_ID_GLOBAL) ?
			WL_PROXD_TLV_ID_FLAGS_MASK : WL_PROXD_TLV_ID_SESSION_FLAGS_MASK;
	for (cfg_idx = 0; cfg_idx < ftm_cfg_cnt; cfg_idx++) {
		p_option_info = (ftm_configs + cfg_idx);
		if (p_option_info != NULL) {
			new_mask = p_option_info->flags;
			/* update flags mask */
			flags_mask |= new_mask;
			if (p_option_info->enable) {
				flags |= new_mask;	/* set the bit on */
			} else {
				flags &= ~new_mask;	/* set the bit off */
			}
		}
	}
	flags = htol32(flags);
	flags_mask = htol32(flags_mask);
	/* setup flags_mask TLV */
	ret = bcm_pack_xtlv_entry((uint8 **)p_tlv, p_buf_space_left,
		type, sizeof(uint32), (uint8 *)&flags_mask, BCM_XTLV_OPTION_ALIGN32);
	if (ret != BCME_OK) {
		DHD_ERROR(("%s : bcm_pack_xltv_entry() for mask flags failed, status=%d\n",
			__FUNCTION__, ret));
		goto exit;
	}

	type = (session_id == WL_PROXD_SESSION_ID_GLOBAL)?
		WL_PROXD_TLV_ID_FLAGS : WL_PROXD_TLV_ID_SESSION_FLAGS;
	/* setup flags TLV */
	ret = bcm_pack_xtlv_entry((uint8 **)p_tlv, p_buf_space_left,
			type, sizeof(uint32), (uint8 *)&flags, BCM_XTLV_OPTION_ALIGN32);
		if (ret != BCME_OK) {
#ifdef RTT_DEBUG
			DHD_RTT(("%s: bcm_pack_xltv_entry() for flags failed, status=%d\n",
				__FUNCTION__, ret));
#endif
		}
exit:
	return ret;
}

static int
rtt_handle_config_general(wl_proxd_session_id_t session_id, wl_proxd_tlv_t **p_tlv,
	uint16 *p_buf_space_left, ftm_config_param_info_t *ftm_configs, int ftm_cfg_cnt)
{
	int ret = BCME_OK;
	int cfg_idx = 0;
	uint32 chanspec;
	ftm_config_param_info_t *p_config_param_info;
	void *p_src_data;
	uint16 src_data_size;	/* size of data pointed by p_src_data as 'source' */
	for (cfg_idx = 0; cfg_idx < ftm_cfg_cnt; cfg_idx++) {
		p_config_param_info = (ftm_configs + cfg_idx);
		if (p_config_param_info != NULL) {
			switch (p_config_param_info->tlvid)	{
			case WL_PROXD_TLV_ID_BSS_INDEX:
			case WL_PROXD_TLV_ID_FTM_RETRIES:
			case WL_PROXD_TLV_ID_FTM_REQ_RETRIES:
				p_src_data = &p_config_param_info->data8;
				src_data_size = sizeof(uint8);
				break;
			case WL_PROXD_TLV_ID_BURST_NUM_FTM:	/* uint16 */
			case WL_PROXD_TLV_ID_NUM_BURST:
			case WL_PROXD_TLV_ID_RX_MAX_BURST:
				p_src_data = &p_config_param_info->data16;
				src_data_size = sizeof(uint16);
				break;
			case WL_PROXD_TLV_ID_TX_POWER:		/* uint32 */
			case WL_PROXD_TLV_ID_RATESPEC:
			case WL_PROXD_TLV_ID_EVENT_MASK:	/* wl_proxd_event_mask_t/uint32 */
			case WL_PROXD_TLV_ID_DEBUG_MASK:
				p_src_data = &p_config_param_info->data32;
				src_data_size = sizeof(uint32);
				break;
			case WL_PROXD_TLV_ID_CHANSPEC:		/* chanspec_t --> 32bit */
				chanspec = p_config_param_info->chanspec;
				p_src_data = (void *) &chanspec;
				src_data_size = sizeof(uint32);
				break;
			case WL_PROXD_TLV_ID_BSSID:		/* mac address */
			case WL_PROXD_TLV_ID_PEER_MAC:
				p_src_data = &p_config_param_info->mac_addr;
				src_data_size = sizeof(struct ether_addr);
				break;
			case WL_PROXD_TLV_ID_BURST_DURATION:	/* wl_proxd_intvl_t */
			case WL_PROXD_TLV_ID_BURST_PERIOD:
			case WL_PROXD_TLV_ID_BURST_FTM_SEP:
			case WL_PROXD_TLV_ID_BURST_TIMEOUT:
			case WL_PROXD_TLV_ID_INIT_DELAY:
				p_src_data = &p_config_param_info->data_intvl;
				src_data_size = sizeof(wl_proxd_intvl_t);
				break;
			default:
				ret = BCME_BADARG;
				break;
			}
			if (ret != BCME_OK) {
				DHD_ERROR(("%s bad TLV ID : %d\n",
					__FUNCTION__, p_config_param_info->tlvid));
				break;
			}

			ret = bcm_pack_xtlv_entry((uint8 **) p_tlv, p_buf_space_left,
				p_config_param_info->tlvid, src_data_size, p_src_data,
				BCM_XTLV_OPTION_ALIGN32);
			if (ret != BCME_OK) {
				DHD_ERROR(("%s: bcm_pack_xltv_entry() failed,"
					" status=%d\n", __FUNCTION__, ret));
				break;
			}

		}
	}
	return ret;
}

static int
dhd_rtt_get_version(dhd_pub_t *dhd, int *out_version)
{
	int ret;
	ftm_subcmd_info_t subcmd_info;
	subcmd_info.name = "ver";
	subcmd_info.cmdid = WL_PROXD_CMD_GET_VERSION;
	subcmd_info.handler = NULL;
	ret = dhd_rtt_common_get_handler(dhd, &subcmd_info,
			WL_PROXD_METHOD_FTM, WL_PROXD_SESSION_ID_GLOBAL);
	*out_version = (ret == BCME_OK) ? subcmd_info.version : 0;
	return ret;
}

static int
dhd_rtt_ftm_enable(dhd_pub_t *dhd, bool enable)
{
	ftm_subcmd_info_t subcmd_info;
	subcmd_info.name = (enable)? "enable" : "disable";
	subcmd_info.cmdid = (enable)? WL_PROXD_CMD_ENABLE: WL_PROXD_CMD_DISABLE;
	subcmd_info.handler = NULL;
	return dhd_rtt_common_set_handler(dhd, &subcmd_info,
			WL_PROXD_METHOD_FTM, WL_PROXD_SESSION_ID_GLOBAL);
}

static int
dhd_rtt_start_session(dhd_pub_t *dhd, wl_proxd_session_id_t session_id, bool start)
{
	ftm_subcmd_info_t subcmd_info;
	subcmd_info.name = (start)? "start session" : "stop session";
	subcmd_info.cmdid = (start)? WL_PROXD_CMD_START_SESSION: WL_PROXD_CMD_STOP_SESSION;
	subcmd_info.handler = NULL;
	return dhd_rtt_common_set_handler(dhd, &subcmd_info,
			WL_PROXD_METHOD_FTM, session_id);
}

static int
dhd_rtt_delete_session(dhd_pub_t *dhd, wl_proxd_session_id_t session_id)
{
	ftm_subcmd_info_t subcmd_info;
	subcmd_info.name = "delete session";
	subcmd_info.cmdid = WL_PROXD_CMD_DELETE_SESSION;
	subcmd_info.handler = NULL;
	return dhd_rtt_common_set_handler(dhd, &subcmd_info,
			WL_PROXD_METHOD_FTM, session_id);
}

static int
dhd_rtt_ftm_config(dhd_pub_t *dhd, wl_proxd_session_id_t session_id,
	ftm_config_category_t catagory, void *ftm_configs, int ftm_cfg_cnt)
{
	ftm_subcmd_info_t subcmd_info;
	wl_proxd_tlv_t *p_tlv;
	/* alloc mem for ioctl headr + reserved 0 bufsize for tlvs (initialize to zero) */
	wl_proxd_iov_t *p_proxd_iov;
	uint16 proxd_iovsize = 0;
	uint16 bufsize;
	uint16 buf_space_left;
	uint16 all_tlvsize;
	int ret = BCME_OK;

	subcmd_info.name = "config";
	subcmd_info.cmdid = WL_PROXD_CMD_CONFIG;

	p_proxd_iov = rtt_alloc_getset_buf(WL_PROXD_METHOD_FTM, session_id, subcmd_info.cmdid,
		FTM_IOC_BUFSZ, &proxd_iovsize);

	if (p_proxd_iov == NULL) {
		DHD_ERROR(("%s : failed to allocate the iovar (size :%d)\n",
			__FUNCTION__, FTM_IOC_BUFSZ));
		return BCME_NOMEM;
	}
	/* setup TLVs */
	bufsize = proxd_iovsize - WL_PROXD_IOV_HDR_SIZE; /* adjust available size for TLVs */
	p_tlv = &p_proxd_iov->tlvs[0];
	/* TLV buffer starts with a full size, will decrement for each packed TLV */
	buf_space_left = bufsize;
	if (catagory == FTM_CONFIG_CAT_OPTIONS) {
		ret = rtt_handle_config_options(session_id, &p_tlv, &buf_space_left,
				(ftm_config_options_info_t *)ftm_configs, ftm_cfg_cnt);
	} else if (catagory == FTM_CONFIG_CAT_GENERAL) {
		ret = rtt_handle_config_general(session_id, &p_tlv, &buf_space_left,
				(ftm_config_param_info_t *)ftm_configs, ftm_cfg_cnt);
	}
	if (ret == BCME_OK) {
		/* update the iov header, set len to include all TLVs + header */
		all_tlvsize = (bufsize - buf_space_left);
		p_proxd_iov->len = htol16(all_tlvsize + WL_PROXD_IOV_HDR_SIZE);
		ret = dhd_iovar(dhd, 0, "proxd", (char *)p_proxd_iov,
			all_tlvsize + WL_PROXD_IOV_HDR_SIZE, TRUE);
		if (ret != BCME_OK) {
			DHD_ERROR(("%s : failed to set config\n", __FUNCTION__));
		}
	}
	/* clean up */
	kfree(p_proxd_iov);
	return ret;
}

chanspec_t
dhd_rtt_convert_to_chspec(wifi_channel_info_t channel)
{
	int bw;
	chanspec_t chanspec = 0;
	uint8 center_chan;
	uint8 primary_chan;
	/* set witdh to 20MHZ for 2.4G HZ */
	if (channel.center_freq >= 2400 && channel.center_freq <= 2500) {
		channel.width = WIFI_CHAN_WIDTH_20;
	}
	switch (channel.width) {
	case WIFI_CHAN_WIDTH_20:
		bw = WL_CHANSPEC_BW_20;
		primary_chan = wf_mhz2channel(channel.center_freq, 0);
		chanspec = wf_channel2chspec(primary_chan, bw);
		break;
	case WIFI_CHAN_WIDTH_40:
		bw = WL_CHANSPEC_BW_40;
		primary_chan = wf_mhz2channel(channel.center_freq, 0);
		chanspec = wf_channel2chspec(primary_chan, bw);
		break;
	case WIFI_CHAN_WIDTH_80:
		bw = WL_CHANSPEC_BW_80;
		primary_chan = wf_mhz2channel(channel.center_freq, 0);
		center_chan = wf_mhz2channel(channel.center_freq0, 0);
		chanspec = wf_chspec_80(center_chan, primary_chan);
		break;
	default:
		DHD_ERROR(("doesn't support this bandwith : %d", channel.width));
		bw = -1;
		break;
	}
	return chanspec;
}

int
dhd_rtt_idx_to_burst_duration(uint idx)
{
	if (idx >= ARRAY_SIZE(burst_duration_idx)) {
		return -1;
	}
	return burst_duration_idx[idx];
}

int
dhd_rtt_set_cfg(dhd_pub_t *dhd, rtt_config_params_t *params)
{
	int err = BCME_OK;
	int idx;
	rtt_status_info_t *rtt_status;
	NULL_CHECK(params, "params is NULL", err);

	NULL_CHECK(dhd, "dhd is NULL", err);
	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);
	if (!HAS_11MC_CAP(rtt_status->rtt_capa.proto)) {
		DHD_ERROR(("doesn't support RTT \n"));
		return BCME_ERROR;
	}
	if (rtt_status->status != RTT_STOPPED) {
		DHD_ERROR(("rtt is already started\n"));
		return BCME_BUSY;
	}
	DHD_RTT(("%s enter\n", __FUNCTION__));

	memset(rtt_status->rtt_config.target_info, 0, TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT));
	rtt_status->rtt_config.rtt_target_cnt = params->rtt_target_cnt;
	memcpy(rtt_status->rtt_config.target_info,
		params->target_info, TARGET_INFO_SIZE(params->rtt_target_cnt));
	rtt_status->status = RTT_STARTED;
	/* start to measure RTT from first device */
	/* find next target to trigger RTT */
	for (idx = rtt_status->cur_idx; idx < rtt_status->rtt_config.rtt_target_cnt; idx++) {
		/* skip the disabled device */
		if (rtt_status->rtt_config.target_info[idx].disable) {
			continue;
		} else {
			/* set the idx to cur_idx */
			rtt_status->cur_idx = idx;
			break;
		}
	}
	if (idx < rtt_status->rtt_config.rtt_target_cnt) {
		DHD_RTT(("rtt_status->cur_idx : %d\n", rtt_status->cur_idx));
		schedule_work(&rtt_status->work);
	}
	return err;
}

int
dhd_rtt_stop(dhd_pub_t *dhd, struct ether_addr *mac_list, int mac_cnt)
{
	int err = BCME_OK;
	int i = 0, j = 0;
	rtt_status_info_t *rtt_status;
	rtt_results_header_t *entry, *next;
	rtt_result_t *rtt_result, *next2;
	struct rtt_noti_callback *iter;

	NULL_CHECK(dhd, "dhd is NULL", err);
	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);
	if (rtt_status->status == RTT_STOPPED) {
		DHD_ERROR(("rtt is not started\n"));
		return BCME_OK;
	}
	DHD_RTT(("%s enter\n", __FUNCTION__));
	mutex_lock(&rtt_status->rtt_mutex);
	for (i = 0; i < mac_cnt; i++) {
		for (j = 0; j < rtt_status->rtt_config.rtt_target_cnt; j++) {
			if (!bcmp(&mac_list[i], &rtt_status->rtt_config.target_info[j].addr,
				ETHER_ADDR_LEN)) {
				rtt_status->rtt_config.target_info[j].disable = TRUE;
			}
		}
	}
	if (rtt_status->all_cancel) {
		/* cancel all of request */
		rtt_status->status = RTT_STOPPED;
		DHD_RTT(("current RTT process is cancelled\n"));
		/* remove the rtt results in cache */
		if (!list_empty(&rtt_status->rtt_results_cache)) {
			/* Iterate rtt_results_header list */
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
			list_for_each_entry_safe(entry, next,
				&rtt_status->rtt_results_cache, list) {
				list_del(&entry->list);
				/* Iterate rtt_result list */
				list_for_each_entry_safe(rtt_result, next2,
					&entry->result_list, list) {
					list_del(&rtt_result->list);
					kfree(rtt_result);
				}
				kfree(entry);
			}
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
		}
		/* send the rtt complete event to wake up the user process */
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
		list_for_each_entry(iter, &rtt_status->noti_fn_list, list) {
			iter->noti_fn(iter->ctx, &rtt_status->rtt_results_cache);
		}
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
		/* reinitialize the HEAD */
		INIT_LIST_HEAD(&rtt_status->rtt_results_cache);
		/* clear information for rtt_config */
		rtt_status->rtt_config.rtt_target_cnt = 0;
		memset(rtt_status->rtt_config.target_info, 0,
			TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT));
		rtt_status->cur_idx = 0;
		dhd_rtt_delete_session(dhd, FTM_DEFAULT_SESSION);
		dhd_rtt_ftm_enable(dhd, FALSE);
	}
	mutex_unlock(&rtt_status->rtt_mutex);
	return err;
}

static int
dhd_rtt_start(dhd_pub_t *dhd)
{
	int err = BCME_OK;
	char eabuf[ETHER_ADDR_STR_LEN];
	char chanbuf[CHANSPEC_STR_LEN];
	int mpc = 0;
	int pm = PM_OFF;
	int ftm_cfg_cnt = 0;
	int ftm_param_cnt = 0;
	uint32 rspec = 0;
	ftm_config_options_info_t ftm_configs[FTM_MAX_CONFIGS];
	ftm_config_param_info_t ftm_params[FTM_MAX_PARAMS];
	rtt_target_info_t *rtt_target;
	rtt_status_info_t *rtt_status;
	struct net_device *dev = dhd_linux_get_primary_netdev(dhd);
	NULL_CHECK(dhd, "dhd is NULL", err);

	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);

	DHD_RTT(("Enter %s\n", __FUNCTION__));
	if (rtt_status->cur_idx >= rtt_status->rtt_config.rtt_target_cnt) {
		err = BCME_RANGE;
		DHD_RTT(("%s : idx %d is out of range\n", __FUNCTION__, rtt_status->cur_idx));
		if (rtt_status->flags == WL_PROXD_SESSION_FLAG_TARGET) {
			DHD_ERROR(("STA is set as Target/Responder \n"));
			return BCME_ERROR;
		}
		goto exit;
	}
	if (RTT_IS_STOPPED(rtt_status)) {
		DHD_RTT(("RTT is stopped\n"));
		goto exit;
	}
	/* turn off mpc in case of non-associted */
	if (!dhd_is_associated(dhd, 0, NULL)) {
		err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc, sizeof(mpc), TRUE);
		if (err) {
			DHD_ERROR(("%s : failed to set mpc\n", __FUNCTION__));
			goto exit;
		}
		rtt_status->mpc = 1; /* Either failure or complete, we need to enable mpc */
	} else {
		/* Save the current power mode */
		rtt_status->pm = PM_OFF;
			err = wldev_ioctl(dev, WLC_GET_PM, &rtt_status->pm, sizeof(rtt_status->pm), false);
		if (err) {
			DHD_ERROR(("Failed to get the PM value\n"));
		} else {
				err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
			if (err) {
				DHD_ERROR(("Failed to set the PM\n"));
				rtt_status->pm_restore = FALSE;
			} else {
				rtt_status->pm_restore = TRUE;
			}
		}
	}
	mutex_lock(&rtt_status->rtt_mutex);
	/* Get a target information */
	rtt_target = &rtt_status->rtt_config.target_info[rtt_status->cur_idx];
	mutex_unlock(&rtt_status->rtt_mutex);
	DHD_RTT(("%s enter\n", __FUNCTION__));
	if (!RTT_IS_ENABLED(rtt_status)) {
		/* enable ftm */
		err = dhd_rtt_ftm_enable(dhd, TRUE);
		if (err) {
			DHD_ERROR(("failed to enable FTM (%d)\n", err));
		goto exit;
	}
	}

	/* delete session of index default sesession  */
	err = dhd_rtt_delete_session(dhd, FTM_DEFAULT_SESSION);
	if (err < 0 && err != BCME_NOTFOUND) {
		DHD_ERROR(("failed to delete session of FTM (%d)\n", err));
		goto exit;
	}
	rtt_status->status = RTT_ENABLED;
	memset(ftm_configs, 0, sizeof(ftm_configs));
	memset(ftm_params, 0, sizeof(ftm_params));

	/* configure the session 1 as initiator */
	ftm_configs[ftm_cfg_cnt].enable = TRUE;
	ftm_configs[ftm_cfg_cnt++].flags = WL_PROXD_SESSION_FLAG_INITIATOR;
	dhd_rtt_ftm_config(dhd, FTM_DEFAULT_SESSION, FTM_CONFIG_CAT_OPTIONS,
		ftm_configs, ftm_cfg_cnt);
	/* target's mac address */
	if (!ETHER_ISNULLADDR(rtt_target->addr.octet)) {
		ftm_params[ftm_param_cnt].mac_addr = rtt_target->addr;
		ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_PEER_MAC;
		DHD_RTT((">\t target %s\n", bcm_ether_ntoa(&rtt_target->addr, eabuf)));
	}
	/* target's chanspec */
	if (rtt_target->chanspec) {
		ftm_params[ftm_param_cnt].chanspec = htol32((uint32)rtt_target->chanspec);
		ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_CHANSPEC;
		DHD_RTT((">\t chanspec : %s\n", wf_chspec_ntoa(rtt_target->chanspec, chanbuf)));
	}
	/* num-burst */
	if (rtt_target->num_burst) {
		ftm_params[ftm_param_cnt].data16 = htol16(rtt_target->num_burst);
		ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_NUM_BURST;
		DHD_RTT((">\t num of burst : %d\n", rtt_target->num_burst));
	}
	/* number of frame per burst */
	if (rtt_target->num_frames_per_burst == 0) {
		rtt_target->num_frames_per_burst =
			CHSPEC_IS20(rtt_target->chanspec) ? FTM_DEFAULT_CNT_20M :
			CHSPEC_IS40(rtt_target->chanspec) ? FTM_DEFAULT_CNT_40M :
			FTM_DEFAULT_CNT_80M;
	}
	ftm_params[ftm_param_cnt].data16 = htol16(rtt_target->num_frames_per_burst);
	ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_BURST_NUM_FTM;
	DHD_RTT((">\t number of frame per burst : %d\n", rtt_target->num_frames_per_burst));
	/* FTM retry count */
	if (rtt_target->num_retries_per_ftm) {
		ftm_params[ftm_param_cnt].data8 = rtt_target->num_retries_per_ftm;
		ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_FTM_RETRIES;
		DHD_RTT((">\t retry count of FTM  : %d\n", rtt_target->num_retries_per_ftm));
	}
	/* FTM Request retry count */
	if (rtt_target->num_retries_per_ftmr) {
		ftm_params[ftm_param_cnt].data8 = rtt_target->num_retries_per_ftmr;
		ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_FTM_REQ_RETRIES;
		DHD_RTT((">\t retry count of FTM Req : %d\n", rtt_target->num_retries_per_ftmr));
	}
	/* burst-period */
	if (rtt_target->burst_period) {
		ftm_params[ftm_param_cnt].data_intvl.intvl =
			htol32(rtt_target->burst_period); /* ms */
		ftm_params[ftm_param_cnt].data_intvl.tmu = WL_PROXD_TMU_MILLI_SEC;
		ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_BURST_PERIOD;
		DHD_RTT((">\t burst period : %d ms\n", rtt_target->burst_period));
	}
	/* burst-duration */
	if (rtt_target->burst_duration) {
		ftm_params[ftm_param_cnt].data_intvl.intvl =
			htol32(rtt_target->burst_duration); /* ms */
		ftm_params[ftm_param_cnt].data_intvl.tmu = WL_PROXD_TMU_MILLI_SEC;
		ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_BURST_DURATION;
		DHD_RTT((">\t burst duration : %d ms\n",
			rtt_target->burst_duration));
	}
	if (rtt_target->bw && rtt_target->preamble) {
		bool use_default = FALSE;
		int nss;
		int mcs;
		switch (rtt_target->preamble) {
		case RTT_PREAMBLE_LEGACY:
			rspec |= WL_RSPEC_ENCODE_RATE; /* 11abg */
			rspec |= WL_RATE_6M;
			break;
		case RTT_PREAMBLE_HT:
			rspec |= WL_RSPEC_ENCODE_HT; /* 11n HT */
		mcs = 0; /* default MCS 0 */
			rspec |= mcs;
			break;
		case RTT_PREAMBLE_VHT:
			rspec |= WL_RSPEC_ENCODE_VHT; /* 11ac VHT */
			mcs = 0; /* default MCS 0 */
			nss = 1; /* default Nss = 1  */
		rspec |= (nss << WL_RSPEC_VHT_NSS_SHIFT) | mcs;
			break;
		default:
			DHD_RTT(("doesn't support this preamble : %d\n", rtt_target->preamble));
			use_default = TRUE;
			break;
		}
		switch (rtt_target->bw) {
		case RTT_BW_20:
			rspec |= WL_RSPEC_BW_20MHZ;
			break;
		case RTT_BW_40:
			rspec |= WL_RSPEC_BW_40MHZ;
			break;
		case RTT_BW_80:
			rspec |= WL_RSPEC_BW_80MHZ;
			break;
		default:
			DHD_RTT(("doesn't support this BW : %d\n", rtt_target->bw));
			use_default = TRUE;
			break;
		}
		if (!use_default) {
			ftm_params[ftm_param_cnt].data32 = htol32(rspec);
			ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_RATESPEC;
			DHD_RTT((">\t ratespec : %d\n", rspec));
	}

	}
	/* use random mac address */
	dhd_set_rand_mac_oui(dhd);
	dhd_rtt_ftm_config(dhd, FTM_DEFAULT_SESSION, FTM_CONFIG_CAT_GENERAL,
		ftm_params, ftm_param_cnt);

	err = dhd_rtt_start_session(dhd, FTM_DEFAULT_SESSION, TRUE);
	if (err) {
		DHD_ERROR(("failed to start session of FTM : error %d\n", err));
	}
exit:
	if (err) {
		DHD_ERROR(("rtt is stopped %s \n", __FUNCTION__));
		rtt_status->status = RTT_STOPPED;
		/* disable FTM */
		dhd_rtt_ftm_enable(dhd, FALSE);
		if (rtt_status->mpc) {
			/* enable mpc again in case of error */
			mpc = 1;
			rtt_status->mpc = 0;
			err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc,
					sizeof(mpc), TRUE);
		}
		if (rtt_status->pm_restore) {
			pm = PM_FAST;
			DHD_ERROR(("pm_restore =%d func =%s \n",
				rtt_status->pm_restore, __FUNCTION__));
			err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
			if (err) {
				DHD_ERROR(("Failed to set PM \n"));
			} else {
				rtt_status->pm_restore = FALSE;
			}
		}
	}
	return err;
}

int
dhd_rtt_register_noti_callback(dhd_pub_t *dhd, void *ctx, dhd_rtt_compl_noti_fn noti_fn)
{
	int err = BCME_OK;
	struct rtt_noti_callback *cb = NULL, *iter;
	rtt_status_info_t *rtt_status;
	NULL_CHECK(dhd, "dhd is NULL", err);
	NULL_CHECK(noti_fn, "noti_fn is NULL", err);

	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);
	spin_lock_bh(&noti_list_lock);
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
	list_for_each_entry(iter, &rtt_status->noti_fn_list, list) {
		if (iter->noti_fn == noti_fn) {
			goto exit;
		}
	}
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
	cb = kmalloc(sizeof(struct rtt_noti_callback), GFP_ATOMIC);
	if (!cb) {
		err = -ENOMEM;
		goto exit;
	}
	cb->noti_fn = noti_fn;
	cb->ctx = ctx;
	list_add(&cb->list, &rtt_status->noti_fn_list);
exit:
	spin_unlock_bh(&noti_list_lock);
	return err;
}

int
dhd_rtt_unregister_noti_callback(dhd_pub_t *dhd, dhd_rtt_compl_noti_fn noti_fn)
{
	int err = BCME_OK;
	struct rtt_noti_callback *cb = NULL, *iter;
	rtt_status_info_t *rtt_status;
	NULL_CHECK(dhd, "dhd is NULL", err);
	NULL_CHECK(noti_fn, "noti_fn is NULL", err);
	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);
	spin_lock_bh(&noti_list_lock);
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
	list_for_each_entry(iter, &rtt_status->noti_fn_list, list) {
		if (iter->noti_fn == noti_fn) {
			cb = iter;
			list_del(&cb->list);
			break;
		}
	}
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

	spin_unlock_bh(&noti_list_lock);
	if (cb) {
		kfree(cb);
	}
	return err;
}

static wifi_rate_t
dhd_rtt_convert_rate_to_host(uint32 rspec)
{
	wifi_rate_t host_rate;
	uint32 bandwidth;
	memset(&host_rate, 0, sizeof(wifi_rate_t));
	if (RSPEC_ISLEGACY(rspec)) {
		host_rate.preamble = 0;
	} else if (RSPEC_ISHT(rspec)) {
		host_rate.preamble = 2;
		host_rate.rateMcsIdx = rspec & WL_RSPEC_RATE_MASK;
	} else if (RSPEC_ISVHT(rspec)) {
		host_rate.preamble = 3;
		host_rate.rateMcsIdx = rspec & WL_RSPEC_VHT_MCS_MASK;
		host_rate.nss = (rspec & WL_RSPEC_VHT_NSS_MASK) >> WL_RSPEC_VHT_NSS_SHIFT;
	}

	bandwidth = RSPEC_BW(rspec);
	switch (bandwidth) {
	case WL_RSPEC_BW_20MHZ:
		host_rate.bw = RTT_RATE_20M;
		break;
	case WL_RSPEC_BW_40MHZ:
		host_rate.bw = RTT_RATE_40M;
		break;
	case WL_RSPEC_BW_80MHZ:
		host_rate.bw = RTT_RATE_80M;
		break;
	case WL_RSPEC_BW_160MHZ:
		host_rate.bw = RTT_RATE_160M;
		break;
	default:
		host_rate.bw = RTT_RATE_20M;
		break;
	}

	host_rate.bitrate = rate_rspec2rate(rspec) / 100; /* 100kbps */
	DHD_RTT(("bit rate : %d\n", host_rate.bitrate));
	return host_rate;
}


static int
dhd_rtt_convert_results_to_host(rtt_report_t *rtt_report, uint8 *p_data, uint16 tlvid, uint16 len)
{
	int err = BCME_OK;
	char eabuf[ETHER_ADDR_STR_LEN];
	wl_proxd_rtt_result_t *p_data_info;
	wl_proxd_result_flags_t flags;
	wl_proxd_session_state_t session_state;
	wl_proxd_status_t proxd_status;
	struct timespec ts;
	uint32 ratespec;
	uint32 avg_dist;
	wl_proxd_rtt_sample_t *p_sample;
	wl_proxd_intvl_t rtt;
	wl_proxd_intvl_t p_time;

	NULL_CHECK(rtt_report, "rtt_report is NULL", err);
	NULL_CHECK(p_data, "p_data is NULL", err);
	DHD_RTT(("%s enter\n", __FUNCTION__));
	p_data_info = (wl_proxd_rtt_result_t *) p_data;
	/* unpack and format 'flags' for display */
	flags = ltoh16_ua(&p_data_info->flags);

	/* session state and status */
	session_state = ltoh16_ua(&p_data_info->state);
	proxd_status = ltoh32_ua(&p_data_info->status);
	DHD_RTT((">\tTarget(%s) session state=%d(%s), status=%d(%s)\n",
		bcm_ether_ntoa((&(p_data_info->peer)), eabuf),
		session_state,
		ftm_session_state_value_to_logstr(session_state),
		proxd_status,
		ftm_status_value_to_logstr(proxd_status)));

	/* show avg_dist (1/256m units), burst_num */
	avg_dist = ltoh32_ua(&p_data_info->avg_dist);
	if (avg_dist == 0xffffffff) {	/* report 'failure' case */
		DHD_RTT((">\tavg_dist=-1m, burst_num=%d, valid_measure_cnt=%d\n",
		ltoh16_ua(&p_data_info->burst_num),
		p_data_info->num_valid_rtt)); /* in a session */
		avg_dist = FTM_INVALID;
	}
	else {
		DHD_RTT((">\tavg_dist=%d.%04dm, burst_num=%d, valid_measure_cnt=%d num_ftm=%d\n",
			avg_dist >> 8, /* 1/256m units */
			((avg_dist & 0xff) * 625) >> 4,
			ltoh16_ua(&p_data_info->burst_num),
			p_data_info->num_valid_rtt,
			p_data_info->num_ftm)); /* in a session */
	}
	/* show 'avg_rtt' sample */
	p_sample = &p_data_info->avg_rtt;
	DHD_RTT((">\tavg_rtt sample: rssi=%d rtt=%d%s std_deviation =%d.%d ratespec=0x%08x\n",
		(int16) ltoh16_ua(&p_sample->rssi),
		ltoh32_ua(&p_sample->rtt.intvl),
		ftm_tmu_value_to_logstr(ltoh16_ua(&p_sample->rtt.tmu)),
		ltoh16_ua(&p_data_info->sd_rtt)/10, ltoh16_ua(&p_data_info->sd_rtt)%10,
		ltoh32_ua(&p_sample->ratespec)));

	/* set peer address */
	rtt_report->addr = p_data_info->peer;
	/* burst num */
	rtt_report->burst_num = ltoh16_ua(&p_data_info->burst_num);
	/* success num */
	rtt_report->success_num = p_data_info->num_valid_rtt;
	/* actual number of FTM supported by peer */
	rtt_report->num_per_burst_peer = p_data_info->num_ftm;
	rtt_report->negotiated_burst_num = p_data_info->num_ftm;
	/* status */
	rtt_report->status = ftm_get_statusmap_info(proxd_status,
			&ftm_status_map_info[0], ARRAYSIZE(ftm_status_map_info));
	/* rssi (0.5db) */
	rtt_report->rssi = ABS((int16) ltoh16_ua(&p_data_info->avg_rtt.rssi)) * 2;
	/* rx rate */
	ratespec = ltoh32_ua(&p_data_info->avg_rtt.ratespec);
	rtt_report->rx_rate = dhd_rtt_convert_rate_to_host(ratespec);
	/* tx rate */
	if (flags & WL_PROXD_RESULT_FLAG_VHTACK) {
		rtt_report->tx_rate = dhd_rtt_convert_rate_to_host(0x2010010);
	} else {
		rtt_report->tx_rate = dhd_rtt_convert_rate_to_host(0xc);
	}
	/* rtt_sd */
	rtt.tmu = ltoh16_ua(&p_data_info->avg_rtt.rtt.tmu);
	rtt.intvl = ltoh32_ua(&p_data_info->avg_rtt.rtt.intvl);
	rtt_report->rtt = FTM_INTVL2NSEC(&rtt) * 1000; /* nano -> pico seconds */
	rtt_report->rtt_sd = ltoh16_ua(&p_data_info->sd_rtt); /* nano -> 0.1 nano */
	DHD_RTT(("rtt_report->rtt : %llu\n", rtt_report->rtt));
	DHD_RTT(("rtt_report->rssi : %d (0.5db)\n", rtt_report->rssi));

	/* average distance */
	if (avg_dist != FTM_INVALID) {
		rtt_report->distance = (avg_dist >> 8) * 1000; /* meter -> mm */
		rtt_report->distance += (avg_dist & 0xff) * 100 / 256;
	} else {
		rtt_report->distance = FTM_INVALID;
	}
	/* time stamp */
	/* get the time elapsed from boot time */
	get_monotonic_boottime(&ts);
	rtt_report->ts = (uint64)TIMESPEC_TO_US(ts);

	if (proxd_status == WL_PROXD_E_REMOTE_FAIL) {
		/* retry time  after failure */
		p_time.intvl = ltoh32_ua(&p_data_info->u.retry_after.intvl);
		p_time.tmu = ltoh16_ua(&p_data_info->u.retry_after.tmu);
		rtt_report->retry_after_duration = FTM_INTVL2SEC(&p_time); /* s -> s */
		DHD_RTT((">\tretry_after: %d%s\n",
			ltoh32_ua(&p_data_info->u.retry_after.intvl),
			ftm_tmu_value_to_logstr(ltoh16_ua(&p_data_info->u.retry_after.tmu))));
	} else {
		/* burst duration */
		p_time.intvl = ltoh32_ua(&p_data_info->u.retry_after.intvl);
		p_time.tmu = ltoh16_ua(&p_data_info->u.retry_after.tmu);
		rtt_report->burst_duration =  FTM_INTVL2MSEC(&p_time); /* s -> ms */
		DHD_RTT((">\tburst_duration: %d%s\n",
			ltoh32_ua(&p_data_info->u.burst_duration.intvl),
			ftm_tmu_value_to_logstr(ltoh16_ua(&p_data_info->u.burst_duration.tmu))));
		DHD_RTT(("rtt_report->burst_duration : %d\n", rtt_report->burst_duration));
	}
	return err;
}

int
dhd_rtt_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data)
{
	int ret = BCME_OK;
	int tlvs_len;
	int idx;
	uint16 version;
	wl_proxd_event_t *p_event;
	wl_proxd_event_type_t event_type;
	wl_proxd_ftm_session_status_t session_status;
	const ftm_strmap_entry_t *p_loginfo;
	rtt_status_info_t *rtt_status;
	rtt_target_info_t *rtt_target_info;
	struct rtt_noti_callback *iter;
	rtt_results_header_t *entry, *next, *rtt_results_header = NULL;
	rtt_result_t *rtt_result, *next2;
	gfp_t kflags;
	bool is_new = TRUE;

	NULL_CHECK(dhd, "dhd is NULL", ret);
	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", ret);

	event_type = ntoh32_ua((void *)&event->event_type);

	DHD_RTT(("Enter %s \n",__FUNCTION__));

	if (event_type != WLC_E_PROXD) {
		DHD_ERROR((" failed event \n"));
		return ret;
	}

	if (RTT_IS_STOPPED(rtt_status)) {
		/* Ignore the Proxd event */
		DHD_RTT((" event handler rtt is stopped \n"));
		if (rtt_status->flags == WL_PROXD_SESSION_FLAG_TARGET) {
			DHD_RTT(("Device is target/Responder. Recv the event. \n"));
		} else {
			return ret;
		}
	}
	if (!event_data) {
		DHD_ERROR(("%s: event_data:NULL\n", __FUNCTION__));
		return -EINVAL;
	}
	p_event = (wl_proxd_event_t *) event_data;
	version = ltoh16(p_event->version);
	if (version < WL_PROXD_API_VERSION) {
		DHD_ERROR(("ignore non-ftm event version = 0x%0x < WL_PROXD_API_VERSION (0x%x)\n",
			version, WL_PROXD_API_VERSION));
		return ret;
	}
	if (!in_atomic()) {
		mutex_lock(&rtt_status->rtt_mutex);
	}
	event_type = (wl_proxd_event_type_t) ltoh16(p_event->type);

	kflags = in_softirq()? GFP_ATOMIC : GFP_KERNEL;

	DHD_RTT(("event_type=0x%x, ntoh16()=0x%x, ltoh16()=0x%x\n",
		p_event->type, ntoh16(p_event->type), ltoh16(p_event->type)));
	p_loginfo = ftm_get_event_type_loginfo(event_type);
	if (p_loginfo == NULL) {
		DHD_ERROR(("receive an invalid FTM event %d\n", event_type));
		goto exit;	/* ignore this event */
		}
	/* get TLVs len, skip over event header */
	if (ltoh16(p_event->len) < OFFSETOF(wl_proxd_event_t, tlvs)) {
		DHD_ERROR(("invalid FTM event length:%d\n", ltoh16(p_event->len)));
		ret = -EINVAL;
		goto exit;
	}
	tlvs_len = ltoh16(p_event->len) - OFFSETOF(wl_proxd_event_t, tlvs);
	DHD_RTT(("receive '%s' event: version=0x%x len=%d method=%d sid=%d tlvs_len=%d\n",
		p_loginfo->text,
		version,
		ltoh16(p_event->len),
		ltoh16(p_event->method),
		ltoh16(p_event->sid),
		tlvs_len));
	rtt_target_info = &rtt_status->rtt_config.target_info[rtt_status->cur_idx];
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
	/* find a rtt_report_header for this mac address */
	list_for_each_entry(entry, &rtt_status->rtt_results_cache, list) {
		if (!memcmp(&entry->peer_mac, &event->addr, ETHER_ADDR_LEN)) {
			/* found a rtt_report_header for peer_mac in the list */
			is_new = FALSE;
			rtt_results_header = entry;
			break;
		}
	}
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
	switch (event_type) {
	case WL_PROXD_EVENT_SESSION_CREATE:
		DHD_RTT(("WL_PROXD_EVENT_SESSION_CREATE\n"));
		break;
	case WL_PROXD_EVENT_SESSION_START:
		DHD_RTT(("WL_PROXD_EVENT_SESSION_START\n"));
		break;
	case WL_PROXD_EVENT_BURST_START:
		DHD_RTT(("WL_PROXD_EVENT_BURST_START\n"));
		break;
	case WL_PROXD_EVENT_BURST_END:
		DHD_RTT(("WL_PROXD_EVENT_BURST_END\n"));
		if (is_new) {
			/* allocate new header for rtt_results */
			rtt_results_header = kzalloc(sizeof(rtt_results_header_t), GFP_KERNEL);
			if (!rtt_results_header) {
				ret = -ENOMEM;
				goto exit;
			}
			/* Initialize the head of list for rtt result */
			INIT_LIST_HEAD(&rtt_results_header->result_list);
			rtt_results_header->peer_mac = event->addr;
			list_add_tail(&rtt_results_header->list, &rtt_status->rtt_results_cache);
		}
		if (tlvs_len > 0) {
			/* allocate rtt_results for new results */
			rtt_result = kzalloc(sizeof(rtt_result_t), kflags);
			if (!rtt_result) {
				ret = -ENOMEM;
				goto exit;
			}
			/* unpack TLVs and invokes the cbfn to print the event content TLVs */
			ret = bcm_unpack_xtlv_buf((void *) &(rtt_result->report),
				(uint8 *)&p_event->tlvs[0], tlvs_len,
				BCM_XTLV_OPTION_ALIGN32, rtt_unpack_xtlv_cbfn);
			if (ret != BCME_OK) {
				DHD_ERROR(("%s : Failed to unpack xtlv for an event\n",
					__FUNCTION__));
				goto exit;
			}
			/* fill out the results from the configuration param */
			rtt_result->report.ftm_num = rtt_target_info->num_frames_per_burst;
			rtt_result->report.type = RTT_TWO_WAY;
			DHD_RTT(("report->ftm_num : %d\n", rtt_result->report.ftm_num));
			rtt_result->report_len = RTT_REPORT_SIZE;

			list_add_tail(&rtt_result->list, &rtt_results_header->result_list);
			rtt_results_header->result_cnt++;
			rtt_results_header->result_tot_len += rtt_result->report_len;
		}
		break;
	case WL_PROXD_EVENT_SESSION_END:
		DHD_RTT(("WL_PROXD_EVENT_SESSION_END\n"));
		if (!RTT_IS_ENABLED(rtt_status)) {
			DHD_RTT(("Ignore the session end evt\n"));
			goto exit;
		}
		if (tlvs_len > 0) {
			/* unpack TLVs and invokes the cbfn to print the event content TLVs */
			ret = bcm_unpack_xtlv_buf((void *) &session_status,
				(uint8 *)&p_event->tlvs[0], tlvs_len,
				BCM_XTLV_OPTION_ALIGN32, rtt_unpack_xtlv_cbfn);
			if (ret != BCME_OK) {
				DHD_ERROR(("%s : Failed to unpack xtlv for an event\n",
					__FUNCTION__));
				goto exit;
			}
		}
		/* In case of no result for the peer device, make fake result for error case */
		if (is_new) {
			/* allocate new header for rtt_results */
			rtt_results_header = kzalloc(sizeof(rtt_results_header_t), GFP_KERNEL);
			if (!rtt_results_header) {
				ret = -ENOMEM;
				goto exit;
			}
			/* Initialize the head of list for rtt result */
			INIT_LIST_HEAD(&rtt_results_header->result_list);
			rtt_results_header->peer_mac = event->addr;
			list_add_tail(&rtt_results_header->list, &rtt_status->rtt_results_cache);

			/* allocate rtt_results for new results */
			rtt_result = kzalloc(sizeof(rtt_result_t), kflags);
			if (!rtt_result) {
				ret = -ENOMEM;
				kfree(rtt_results_header);
				goto exit;
			}
			/* fill out the results from the configuration param */
			rtt_result->report.ftm_num = rtt_target_info->num_frames_per_burst;
			rtt_result->report.type = RTT_TWO_WAY;
			DHD_RTT(("report->ftm_num : %d\n", rtt_result->report.ftm_num));
			rtt_result->report_len = RTT_REPORT_SIZE;
			rtt_result->report.status = RTT_REASON_FAIL_NO_RSP;
			rtt_result->report.addr = rtt_target_info->addr;
			rtt_result->report.distance = FTM_INVALID;
			list_add_tail(&rtt_result->list, &rtt_results_header->result_list);
			rtt_results_header->result_cnt++;
			rtt_results_header->result_tot_len += rtt_result->report_len;
		}
		/* find next target to trigger RTT */
		for (idx = (rtt_status->cur_idx + 1);
			idx < rtt_status->rtt_config.rtt_target_cnt; idx++) {
			/* skip the disabled device */
			if (rtt_status->rtt_config.target_info[idx].disable) {
				continue;
			} else {
				/* set the idx to cur_idx */
				rtt_status->cur_idx = idx;
				break;
			}
		}
		if (idx < rtt_status->rtt_config.rtt_target_cnt) {
			/* restart to measure RTT from next device */
			DHD_ERROR(("restart to measure rtt\n"));
			schedule_work(&rtt_status->work);
		} else {
			DHD_RTT(("RTT_STOPPED\n"));
			rtt_status->status = RTT_STOPPED;
			/* to turn on mpc mode */
			schedule_work(&rtt_status->work);
			/* notify the completed information to others */
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
			list_for_each_entry(iter, &rtt_status->noti_fn_list, list) {
				iter->noti_fn(iter->ctx, &rtt_status->rtt_results_cache);
			}
			/* remove the rtt results in cache */
			if (!list_empty(&rtt_status->rtt_results_cache)) {
				/* Iterate rtt_results_header list */
				list_for_each_entry_safe(entry, next,
				&rtt_status->rtt_results_cache, list) {
					list_del(&entry->list);
					/* Iterate rtt_result list */
					list_for_each_entry_safe(rtt_result, next2,
						&entry->result_list, list) {
				list_del(&rtt_result->list);
				kfree(rtt_result);
			}
					kfree(entry);
				}
			}
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
			/* reinitialize the HEAD */
			INIT_LIST_HEAD(&rtt_status->rtt_results_cache);
			/* clear information for rtt_config */
			rtt_status->rtt_config.rtt_target_cnt = 0;
			memset(rtt_status->rtt_config.target_info, 0,
				TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT));
			rtt_status->cur_idx = 0;
		}
		break;
	case WL_PROXD_EVENT_SESSION_RESTART:
		DHD_RTT(("WL_PROXD_EVENT_SESSION_RESTART\n"));
		break;
	case WL_PROXD_EVENT_BURST_RESCHED:
		DHD_RTT(("WL_PROXD_EVENT_BURST_RESCHED\n"));
		break;
	case WL_PROXD_EVENT_SESSION_DESTROY:
		DHD_RTT(("WL_PROXD_EVENT_SESSION_DESTROY\n"));
		break;
	case WL_PROXD_EVENT_FTM_FRAME:
		DHD_RTT(("WL_PROXD_EVENT_FTM_FRAME\n"));
		break;
	case WL_PROXD_EVENT_DELAY:
		DHD_RTT(("WL_PROXD_EVENT_DELAY\n"));
		break;
	case WL_PROXD_EVENT_VS_INITIATOR_RPT:
		DHD_RTT(("WL_PROXD_EVENT_VS_INITIATOR_RPT\n "));
		break;
	case WL_PROXD_EVENT_RANGING:
		DHD_RTT(("WL_PROXD_EVENT_RANGING\n"));
		break;

	default:
		DHD_ERROR(("WLC_E_PROXD: not supported EVENT Type:%d\n", event_type));
		break;
	}
exit:
	if (!in_atomic()) {
		mutex_unlock(&rtt_status->rtt_mutex);
	}

	return ret;
}

static void
dhd_rtt_work(struct work_struct *work)
{
	rtt_status_info_t *rtt_status;
	dhd_pub_t *dhd;
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
	rtt_status = container_of(work, rtt_status_info_t, work);
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
	if (rtt_status == NULL) {
		DHD_ERROR(("%s : rtt_status is NULL\n", __FUNCTION__));
		return;
	}
	dhd = rtt_status->dhd;
	if (dhd == NULL) {
		DHD_ERROR(("%s : dhd is NULL\n", __FUNCTION__));
		return;
	}
	(void) dhd_rtt_start(dhd);
}

int
dhd_rtt_capability(dhd_pub_t *dhd, rtt_capabilities_t *capa)
{
	rtt_status_info_t *rtt_status;
	int err = BCME_OK;
	NULL_CHECK(dhd, "dhd is NULL", err);
	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);
	NULL_CHECK(capa, "capa is NULL", err);
	bzero(capa, sizeof(rtt_capabilities_t));

	/* set rtt capabilities */
	if (rtt_status->rtt_capa.proto & RTT_CAP_ONE_WAY)
		capa->rtt_one_sided_supported = 1;
	if (rtt_status->rtt_capa.proto & RTT_CAP_FTM_WAY)
		capa->rtt_ftm_supported = 1;
	if (rtt_status->rtt_capa.feature & RTT_FEATURE_LCI)
		capa->lci_support = 1;
	if (rtt_status->rtt_capa.feature & RTT_FEATURE_LCR)
		capa->lcr_support = 1;
	if (rtt_status->rtt_capa.feature & RTT_FEATURE_PREAMBLE)
		capa->preamble_support = 1;
	if (rtt_status->rtt_capa.feature & RTT_FEATURE_BW)
		capa->bw_support = 1;
	/* bit mask */
	capa->preamble_support = rtt_status->rtt_capa.preamble;
	capa->bw_support = rtt_status->rtt_capa.bw;

	return err;
}

int
dhd_rtt_avail_channel(dhd_pub_t *dhd, wifi_channel_info *channel_info)
{
	u32 chanspec = 0;
	int err = BCME_OK;
	chanspec_t c = 0;
	u32 channel;
	struct net_device *dev = dhd_linux_get_primary_netdev(dhd);

	if ((err = wldev_iovar_getint(dev, "chanspec",
		(s32 *)&chanspec)) == BCME_OK) {
		c = (chanspec_t)dtoh32(chanspec);
		c = wl_chspec_driver_to_host(c);
		channel  = wf_chspec_ctlchan(c);
		DHD_RTT((" control channel is %d \n", channel));
		if (CHSPEC_IS20(c)) {
			channel_info->width = WIFI_CHAN_WIDTH_20;
			DHD_RTT((" band is 20 \n"));
		} else if (CHSPEC_IS40(c)) {
			channel_info->width = WIFI_CHAN_WIDTH_40;
			DHD_RTT(("band is 40 \n"));
		} else {
			channel_info->width = WIFI_CHAN_WIDTH_80;
			DHD_RTT(("band is 80 \n"));
	}
		if (CHSPEC_IS2G(c) && (channel >= CH_MIN_2G_CHANNEL) &&
			(channel <= CH_MAX_2G_CHANNEL)) {
			channel_info->center_freq =
				ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
		} else if (CHSPEC_IS5G(c) && channel >= CH_MIN_5G_CHANNEL) {
			channel_info->center_freq =
				ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
	}
		if ((channel_info->width == WIFI_CHAN_WIDTH_80) ||
			(channel_info->width == WIFI_CHAN_WIDTH_40)) {
			channel = CHSPEC_CHANNEL(c);
			channel_info->center_freq0 =
				ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
		}
	} else {
		DHD_ERROR(("Failed to get the chanspec \n"));
	}
	return err;
}

int
dhd_rtt_enable_responder(dhd_pub_t *dhd, wifi_channel_info *channel_info)
{
	int err = BCME_OK;
	char chanbuf[CHANSPEC_STR_LEN];
	int mpc = 0;
	int pm = PM_OFF;
	int ftm_cfg_cnt = 0;
	chanspec_t chanspec;
	wifi_channel_info_t channel;
	struct net_device *dev = dhd_linux_get_primary_netdev(dhd);
	ftm_config_options_info_t ftm_configs[FTM_MAX_CONFIGS];
	ftm_config_param_info_t ftm_params[FTM_MAX_PARAMS];
	rtt_status_info_t *rtt_status;
	NULL_CHECK(dhd, "dhd is NULL", err);
	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);

	if (RTT_IS_STOPPED(rtt_status)) {
		DHD_RTT(("STA responder/Target. \n"));
	}
	DHD_RTT(("Enter %s \n", __FUNCTION__));
	/* turn off mpc in case of non-associted */
	if (!dhd_is_associated(dhd, 0, NULL)) {
		err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc, sizeof(mpc), TRUE);
		if (err) {
			DHD_ERROR(("%s : failed to set mpc\n", __FUNCTION__));
			goto exit;
		}
		rtt_status->mpc = 1; /* Either failure or complete, we need to enable mpc */
		DHD_RTT(("mpc set \n"));

			channel.width = WIFI_CHAN_WIDTH_80;
		channel.center_freq = 5180;
		channel.center_freq0 = 5210;
		chanspec =  dhd_rtt_convert_to_chspec(channel);
		DHD_RTT(("Default chanspec/channel set as %s for rtt.\n",
			wf_chspec_ntoa(chanspec, chanbuf)));
		err = wldev_iovar_setint(dev, "chanspec", chanspec);
		if (err) {
			DHD_ERROR(("Failed to set the chanspec \n"));
		}
	}
	/* Need to set PM=0 if STA is going to set as responder. */
	rtt_status->pm = PM_OFF;
	err = wldev_ioctl(dev, WLC_GET_PM, &rtt_status->pm, sizeof(rtt_status->pm), false);
	DHD_RTT(("Current PM value read %d\n", rtt_status->pm));
	if (err) {
		DHD_ERROR(("Failed to get the PM value \n"));
	} else {
		err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
		if (err) {
			DHD_ERROR(("Failed to set the PM \n"));
			rtt_status->pm_restore = FALSE;
		} else {
			rtt_status->pm_restore = TRUE;
		}
	}

	if (!RTT_IS_ENABLED(rtt_status)) {
		/* enable ftm */
		err = dhd_rtt_ftm_enable(dhd, TRUE);
		if (err) {
			DHD_ERROR(("Failed to enable FTM (%d)\n", err));
			goto exit;
		}
		DHD_RTT(("FTM enabled \n"));
	}

	rtt_status->status = RTT_ENABLED;
	DHD_RTT(("Responder enabled \n"));
	memset(ftm_configs, 0, sizeof(ftm_configs));
	memset(ftm_params, 0, sizeof(ftm_params));

	/* configure the session 1 as target */
	ftm_configs[ftm_cfg_cnt].enable = TRUE;
	ftm_configs[ftm_cfg_cnt++].flags = WL_PROXD_SESSION_FLAG_TARGET;
	rtt_status->flags = WL_PROXD_SESSION_FLAG_TARGET;
	DHD_RTT(("Set the device as responder \n"));
	err = dhd_rtt_ftm_config(dhd, FTM_DEFAULT_SESSION, FTM_CONFIG_CAT_OPTIONS,
		ftm_configs, ftm_cfg_cnt);
exit:
	if (err) {
		rtt_status->status = RTT_STOPPED;
		DHD_ERROR(("rtt is stopped  %s \n", __FUNCTION__));
		/* disable FTM */
		dhd_rtt_ftm_enable(dhd, FALSE);
		if (rtt_status->mpc) {
			/* enable mpc again in case of error */
			mpc = 1;
			rtt_status->mpc = 0;
			err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc,
					sizeof(mpc), TRUE);
		}
		DHD_RTT(("restoring the PM value \n"));
		if (rtt_status->pm_restore) {
			pm = PM_FAST;
			err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
			if (err) {
				DHD_ERROR(("Failed to restore PM \n"));
			} else {
				rtt_status->pm_restore = FALSE;
			}
		}
	}

	return err;
}

int
dhd_rtt_cancel_responder(dhd_pub_t *dhd)
{
	int err = BCME_OK;
	rtt_status_info_t *rtt_status;
	int mpc = 0;
	int pm = 0;
	struct net_device *dev = dhd_linux_get_primary_netdev(dhd);

	NULL_CHECK(dhd, "dhd is NULL", err);
	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);

	DHD_RTT(("Enter %s \n", __FUNCTION__));
	err = dhd_rtt_ftm_enable(dhd, FALSE);
	if (err) {
		DHD_ERROR(("failed to disable FTM (%d)\n", err));
	}
	rtt_status->status = RTT_STOPPED;

	if (rtt_status->mpc) {
		/* enable mpc again in case of cancelling responder */
		mpc = 1;
		rtt_status->mpc = 0;
		err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc, sizeof(mpc), TRUE);
	}
	if (rtt_status->pm_restore) {
		pm = PM_FAST;
		DHD_RTT(("pm_restore =%d \n", rtt_status->pm_restore));
		err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
		if (err) {
			DHD_ERROR(("Failed to restore PM \n"));
		} else {
			rtt_status->pm_restore = FALSE;
		}
	}
	return err;
}

int
dhd_rtt_init(dhd_pub_t *dhd)
{
	int err = BCME_OK, ret;
	int32 up = 1;
	int32 version;
	rtt_status_info_t *rtt_status;
	NULL_CHECK(dhd, "dhd is NULL", err);
	if (dhd->rtt_state) {
		return err;
	}
	dhd->rtt_state = kzalloc(sizeof(rtt_status_info_t), GFP_KERNEL);
	if (dhd->rtt_state == NULL) {
		err = BCME_NOMEM;
		DHD_ERROR(("%s : failed to create rtt_state\n", __FUNCTION__));
		return err;
	}
	bzero(dhd->rtt_state, sizeof(rtt_status_info_t));
	rtt_status = GET_RTTSTATE(dhd);
	rtt_status->rtt_config.target_info =
			kzalloc(TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT), GFP_KERNEL);
	if (rtt_status->rtt_config.target_info == NULL) {
		DHD_ERROR(("%s failed to allocate the target info for %d\n",
			__FUNCTION__, RTT_MAX_TARGET_CNT));
		err = BCME_NOMEM;
		goto exit;
	}
	rtt_status->dhd = dhd;
	/* need to do WLC_UP  */
	dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&up, sizeof(int32), TRUE, 0);

	ret = dhd_rtt_get_version(dhd, &version);
	if (ret == BCME_OK && (version == WL_PROXD_API_VERSION)) {
		DHD_ERROR(("%s : FTM is supported\n", __FUNCTION__));
		/* rtt_status->rtt_capa.proto |= RTT_CAP_ONE_WAY; */
		rtt_status->rtt_capa.proto |= RTT_CAP_FTM_WAY;

		/* indicate to set tx rate */
		rtt_status->rtt_capa.feature |= RTT_FEATURE_LCI;
		rtt_status->rtt_capa.feature |= RTT_FEATURE_LCR;
		rtt_status->rtt_capa.feature |= RTT_FEATURE_PREAMBLE;
		rtt_status->rtt_capa.preamble |= RTT_PREAMBLE_VHT;
		rtt_status->rtt_capa.preamble |= RTT_PREAMBLE_HT;

		/* indicate to set bandwith */
		rtt_status->rtt_capa.feature |= RTT_FEATURE_BW;
		rtt_status->rtt_capa.bw |= RTT_BW_20;
		rtt_status->rtt_capa.bw |= RTT_BW_40;
		rtt_status->rtt_capa.bw |= RTT_BW_80;
	} else {
		if ((ret != BCME_OK) || (version == 0)) {
			DHD_ERROR(("%s : FTM is not supported\n", __FUNCTION__));
		} else {
			DHD_ERROR(("%s : FTM version mismatch between HOST (%d) and FW (%d)\n",
				__FUNCTION__, WL_PROXD_API_VERSION, version));
	}
	}
	/* cancel all of RTT request once we got the cancel request */
	rtt_status->all_cancel = TRUE;
	mutex_init(&rtt_status->rtt_mutex);
	INIT_LIST_HEAD(&rtt_status->noti_fn_list);
	INIT_LIST_HEAD(&rtt_status->rtt_results_cache);
	INIT_WORK(&rtt_status->work, dhd_rtt_work);
exit:
	if (err < 0) {
		kfree(rtt_status->rtt_config.target_info);
		kfree(dhd->rtt_state);
	}
	return err;
}

int
dhd_rtt_deinit(dhd_pub_t *dhd)
{
	int err = BCME_OK;
	rtt_status_info_t *rtt_status;
	rtt_results_header_t *rtt_header, *next;
	rtt_result_t *rtt_result, *next2;
	struct rtt_noti_callback *iter, *iter2;
	NULL_CHECK(dhd, "dhd is NULL", err);
	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);
	rtt_status->status = RTT_STOPPED;
	DHD_RTT(("rtt is stopped %s \n", __FUNCTION__));
	/* clear evt callback list */
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif

	if (!list_empty(&rtt_status->noti_fn_list)) {
		list_for_each_entry_safe(iter, iter2, &rtt_status->noti_fn_list, list) {
			list_del(&iter->list);
			kfree(iter);
		}
	}
	/* remove the rtt results */
	if (!list_empty(&rtt_status->rtt_results_cache)) {
		list_for_each_entry_safe(rtt_header, next, &rtt_status->rtt_results_cache, list) {
			list_del(&rtt_header->list);
			list_for_each_entry_safe(rtt_result, next2,
				&rtt_header->result_list, list) {
			list_del(&rtt_result->list);
			kfree(rtt_result);
		}
			kfree(rtt_header);
	}
	}
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
	kfree(rtt_status->rtt_config.target_info);
	kfree(dhd->rtt_state);
	dhd->rtt_state = NULL;
	return err;
}
