xref: /OK3568_Linux_fs/external/rkwifibt/drivers/bcmdhd/dhd_rtt.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Broadcom Dongle Host Driver (DHD), RTT
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2020, Broadcom.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  *      Unless you and Broadcom execute a separate written software license
7*4882a593Smuzhiyun  * agreement governing use of this software, this software is licensed to you
8*4882a593Smuzhiyun  * under the terms of the GNU General Public License version 2 (the "GPL"),
9*4882a593Smuzhiyun  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10*4882a593Smuzhiyun  * following added to such license:
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  *      As a special exception, the copyright holders of this software give you
13*4882a593Smuzhiyun  * permission to link this software with independent modules, and to copy and
14*4882a593Smuzhiyun  * distribute the resulting executable under terms of your choice, provided that
15*4882a593Smuzhiyun  * you also meet, for each linked independent module, the terms and conditions of
16*4882a593Smuzhiyun  * the license of that module.  An independent module is a module which is not
17*4882a593Smuzhiyun  * derived from this software.  The special exception does not apply to any
18*4882a593Smuzhiyun  * modifications of the software.
19*4882a593Smuzhiyun  *
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * <<Broadcom-WL-IPTag/Dual:>>
22*4882a593Smuzhiyun  */
23*4882a593Smuzhiyun #ifndef __DHD_RTT_H__
24*4882a593Smuzhiyun #define __DHD_RTT_H__
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #include <dngl_stats.h>
27*4882a593Smuzhiyun #include "wifi_stats.h"
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #define RTT_MAX_TARGET_CNT 50
30*4882a593Smuzhiyun #define RTT_MAX_FRAME_CNT 25
31*4882a593Smuzhiyun #define RTT_MAX_RETRY_CNT 10
32*4882a593Smuzhiyun #define DEFAULT_FTM_CNT 6
33*4882a593Smuzhiyun #define DEFAULT_RETRY_CNT 6
34*4882a593Smuzhiyun #define DEFAULT_FTM_FREQ 5180
35*4882a593Smuzhiyun #define DEFAULT_FTM_CNTR_FREQ0 5210
36*4882a593Smuzhiyun #define RTT_MAX_GEOFENCE_TARGET_CNT 8
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #define TARGET_INFO_SIZE(count) (sizeof(rtt_target_info_t) * count)
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #define TARGET_TYPE(target) (target->type)
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #define RTT_IS_ENABLED(rtt_status) (rtt_status->status == RTT_ENABLED)
43*4882a593Smuzhiyun #define RTT_IS_STOPPED(rtt_status) (rtt_status->status == RTT_STOPPED)
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun #define GEOFENCE_RTT_LOCK(rtt_status) mutex_lock(&(rtt_status)->geofence_mutex)
46*4882a593Smuzhiyun #define GEOFENCE_RTT_UNLOCK(rtt_status) mutex_unlock(&(rtt_status)->geofence_mutex)
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #ifndef BIT
49*4882a593Smuzhiyun #define BIT(x) (1 << (x))
50*4882a593Smuzhiyun #endif
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun /* DSSS, CCK and 802.11n rates in [500kbps] units */
53*4882a593Smuzhiyun #define WL_MAXRATE	108	/* in 500kbps units */
54*4882a593Smuzhiyun #define WL_RATE_1M	2	/* in 500kbps units */
55*4882a593Smuzhiyun #define WL_RATE_2M	4	/* in 500kbps units */
56*4882a593Smuzhiyun #define WL_RATE_5M5	11	/* in 500kbps units */
57*4882a593Smuzhiyun #define WL_RATE_11M	22	/* in 500kbps units */
58*4882a593Smuzhiyun #define WL_RATE_6M	12	/* in 500kbps units */
59*4882a593Smuzhiyun #define WL_RATE_9M	18	/* in 500kbps units */
60*4882a593Smuzhiyun #define WL_RATE_12M	24	/* in 500kbps units */
61*4882a593Smuzhiyun #define WL_RATE_18M	36	/* in 500kbps units */
62*4882a593Smuzhiyun #define WL_RATE_24M	48	/* in 500kbps units */
63*4882a593Smuzhiyun #define WL_RATE_36M	72	/* in 500kbps units */
64*4882a593Smuzhiyun #define WL_RATE_48M	96	/* in 500kbps units */
65*4882a593Smuzhiyun #define WL_RATE_54M	108	/* in 500kbps units */
66*4882a593Smuzhiyun #define GET_RTTSTATE(dhd) ((rtt_status_info_t *)dhd->rtt_state)
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun #ifdef WL_NAN
69*4882a593Smuzhiyun /* RTT Retry Timer Interval */
70*4882a593Smuzhiyun /* Fix Me: Revert back once retry logic is back in place */
71*4882a593Smuzhiyun #define DHD_RTT_RETRY_TIMER_INTERVAL_MS			-1
72*4882a593Smuzhiyun #endif /* WL_NAN */
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun #define DHD_RTT_INVALID_TARGET_INDEX		-1
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun enum rtt_role {
77*4882a593Smuzhiyun 	RTT_INITIATOR = 0,
78*4882a593Smuzhiyun 	RTT_TARGET = 1
79*4882a593Smuzhiyun };
80*4882a593Smuzhiyun enum rtt_status {
81*4882a593Smuzhiyun 	RTT_STOPPED = 0,
82*4882a593Smuzhiyun 	RTT_STARTED = 1,
83*4882a593Smuzhiyun 	RTT_ENABLED = 2
84*4882a593Smuzhiyun };
85*4882a593Smuzhiyun typedef int64_t wifi_timestamp; /* In microseconds (us) */
86*4882a593Smuzhiyun typedef int64_t wifi_timespan;
87*4882a593Smuzhiyun typedef int32 wifi_rssi_rtt;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun typedef enum {
90*4882a593Smuzhiyun 	RTT_INVALID,
91*4882a593Smuzhiyun 	RTT_ONE_WAY,
92*4882a593Smuzhiyun 	RTT_TWO_WAY,
93*4882a593Smuzhiyun 	RTT_AUTO
94*4882a593Smuzhiyun } rtt_type_t;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun /* RTT peer type */
97*4882a593Smuzhiyun typedef enum {
98*4882a593Smuzhiyun 	RTT_PEER_AP         = 0x1,
99*4882a593Smuzhiyun 	RTT_PEER_STA        = 0x2,
100*4882a593Smuzhiyun 	RTT_PEER_P2P_GO     = 0x3,
101*4882a593Smuzhiyun 	RTT_PEER_P2P_CLIENT = 0x4,
102*4882a593Smuzhiyun 	RTT_PEER_NAN        = 0x5,
103*4882a593Smuzhiyun 	RTT_PEER_INVALID    = 0x6
104*4882a593Smuzhiyun } rtt_peer_type_t;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun /* Ranging status */
107*4882a593Smuzhiyun typedef enum rtt_reason {
108*4882a593Smuzhiyun 	RTT_STATUS_SUCCESS       = 0,
109*4882a593Smuzhiyun 	RTT_STATUS_FAILURE       = 1,           // general failure status
110*4882a593Smuzhiyun 	RTT_STATUS_FAIL_NO_RSP   = 2,           // target STA does not respond to request
111*4882a593Smuzhiyun 	RTT_STATUS_FAIL_REJECTED = 3,           // request rejected. Applies to 2-sided RTT only
112*4882a593Smuzhiyun 	RTT_STATUS_FAIL_NOT_SCHEDULED_YET  = 4,
113*4882a593Smuzhiyun 	RTT_STATUS_FAIL_TM_TIMEOUT         = 5, // timing measurement times out
114*4882a593Smuzhiyun 	RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6, // Target on different channel, cannot range
115*4882a593Smuzhiyun 	RTT_STATUS_FAIL_NO_CAPABILITY  = 7,     // ranging not supported
116*4882a593Smuzhiyun 	RTT_STATUS_ABORTED             = 8,     // request aborted for unknown reason
117*4882a593Smuzhiyun 	RTT_STATUS_FAIL_INVALID_TS     = 9,     // Invalid T1-T4 timestamp
118*4882a593Smuzhiyun 	RTT_STATUS_FAIL_PROTOCOL       = 10,    // 11mc protocol failed
119*4882a593Smuzhiyun 	RTT_STATUS_FAIL_SCHEDULE       = 11,    // request could not be scheduled
120*4882a593Smuzhiyun 	RTT_STATUS_FAIL_BUSY_TRY_LATER = 12,    // responder cannot collaborate at time of request
121*4882a593Smuzhiyun 	RTT_STATUS_INVALID_REQ         = 13,    // bad request args
122*4882a593Smuzhiyun 	RTT_STATUS_NO_WIFI             = 14,    // WiFi not enabled Responder overrides param info
123*4882a593Smuzhiyun 						// cannot range with new params
124*4882a593Smuzhiyun 	RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
125*4882a593Smuzhiyun } rtt_reason_t;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun enum {
128*4882a593Smuzhiyun 	RTT_CAP_ONE_WAY	 = BIT(0),
129*4882a593Smuzhiyun 	/* IEEE802.11mc */
130*4882a593Smuzhiyun 	RTT_CAP_FTM_WAY  = BIT(1)
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun enum {
134*4882a593Smuzhiyun 	RTT_FEATURE_LCI = BIT(0),
135*4882a593Smuzhiyun 	RTT_FEATURE_LCR = BIT(1),
136*4882a593Smuzhiyun 	RTT_FEATURE_PREAMBLE = BIT(2),
137*4882a593Smuzhiyun 	RTT_FEATURE_BW = BIT(3)
138*4882a593Smuzhiyun };
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun enum {
141*4882a593Smuzhiyun 	RTT_PREAMBLE_LEGACY = BIT(0),
142*4882a593Smuzhiyun 	RTT_PREAMBLE_HT = BIT(1),
143*4882a593Smuzhiyun 	RTT_PREAMBLE_VHT = BIT(2)
144*4882a593Smuzhiyun };
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun enum {
147*4882a593Smuzhiyun 	RTT_BW_5 = BIT(0),
148*4882a593Smuzhiyun 	RTT_BW_10 = BIT(1),
149*4882a593Smuzhiyun 	RTT_BW_20 = BIT(2),
150*4882a593Smuzhiyun 	RTT_BW_40 = BIT(3),
151*4882a593Smuzhiyun 	RTT_BW_80 = BIT(4),
152*4882a593Smuzhiyun 	RTT_BW_160 = BIT(5)
153*4882a593Smuzhiyun };
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun enum rtt_rate_bw {
156*4882a593Smuzhiyun 	RTT_RATE_20M,
157*4882a593Smuzhiyun 	RTT_RATE_40M,
158*4882a593Smuzhiyun 	RTT_RATE_80M,
159*4882a593Smuzhiyun 	RTT_RATE_160M
160*4882a593Smuzhiyun };
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun typedef enum ranging_type {
163*4882a593Smuzhiyun 	RTT_TYPE_INVALID	=	0,
164*4882a593Smuzhiyun 	RTT_TYPE_LEGACY		=	1,
165*4882a593Smuzhiyun 	RTT_TYPE_NAN_DIRECTED	=	2,
166*4882a593Smuzhiyun 	RTT_TYPE_NAN_GEOFENCE	=	3
167*4882a593Smuzhiyun } ranging_type_t;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun typedef enum ranging_target_list_mode {
170*4882a593Smuzhiyun 	RNG_TARGET_LIST_MODE_INVALID	=	0,
171*4882a593Smuzhiyun 	RNG_TARGET_LIST_MODE_LEGACY	=	1,
172*4882a593Smuzhiyun 	RNG_TARGET_LIST_MODE_NAN	=	2,
173*4882a593Smuzhiyun 	RNG_TARGET_LIST_MODE_MIX	=	3
174*4882a593Smuzhiyun } ranging_target_list_mode_t;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun #define FTM_MAX_NUM_BURST_EXP	14
177*4882a593Smuzhiyun #define HAS_11MC_CAP(cap) (cap & RTT_CAP_FTM_WAY)
178*4882a593Smuzhiyun #define HAS_ONEWAY_CAP(cap) (cap & RTT_CAP_ONE_WAY)
179*4882a593Smuzhiyun #define HAS_RTT_CAP(cap) (HAS_ONEWAY_CAP(cap) || HAS_11MC_CAP(cap))
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun typedef struct rtt_target_info {
182*4882a593Smuzhiyun 	struct ether_addr addr;
183*4882a593Smuzhiyun 	struct ether_addr local_addr;
184*4882a593Smuzhiyun 	rtt_type_t type; /* rtt_type */
185*4882a593Smuzhiyun 	rtt_peer_type_t peer; /* peer type */
186*4882a593Smuzhiyun 	wifi_channel_info channel; /* channel information */
187*4882a593Smuzhiyun 	chanspec_t chanspec; /* chanspec for channel */
188*4882a593Smuzhiyun 	bool	disable; /* disable for RTT measurement */
189*4882a593Smuzhiyun 	/*
190*4882a593Smuzhiyun 	* Time interval between bursts (units: 100 ms).
191*4882a593Smuzhiyun 	* Applies to 1-sided and 2-sided RTT multi-burst requests.
192*4882a593Smuzhiyun 	* Range: 0-31, 0: no preference by initiator (2-sided RTT)
193*4882a593Smuzhiyun 	*/
194*4882a593Smuzhiyun 	uint32	burst_period;
195*4882a593Smuzhiyun 	/*
196*4882a593Smuzhiyun 	* Total number of RTT bursts to be executed. It will be
197*4882a593Smuzhiyun 	* specified in the same way as the parameter "Number of
198*4882a593Smuzhiyun 	* Burst Exponent" found in the FTM frame format. It
199*4882a593Smuzhiyun 	* applies to both: 1-sided RTT and 2-sided RTT. Valid
200*4882a593Smuzhiyun 	* values are 0 to 15 as defined in 802.11mc std.
201*4882a593Smuzhiyun 	* 0 means single shot
202*4882a593Smuzhiyun 	* The implication of this parameter on the maximum
203*4882a593Smuzhiyun 	* number of RTT results is the following:
204*4882a593Smuzhiyun 	* for 1-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst)
205*4882a593Smuzhiyun 	* for 2-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst - 1)
206*4882a593Smuzhiyun 	*/
207*4882a593Smuzhiyun 	uint16 num_burst;
208*4882a593Smuzhiyun 	/*
209*4882a593Smuzhiyun 	* num of frames per burst.
210*4882a593Smuzhiyun 	* Minimum value = 1, Maximum value = 31
211*4882a593Smuzhiyun 	* For 2-sided this equals the number of FTM frames
212*4882a593Smuzhiyun 	* to be attempted in a single burst. This also
213*4882a593Smuzhiyun 	* equals the number of FTM frames that the
214*4882a593Smuzhiyun 	* initiator will request that the responder send
215*4882a593Smuzhiyun 	* in a single frame
216*4882a593Smuzhiyun 	*/
217*4882a593Smuzhiyun 	uint32 num_frames_per_burst;
218*4882a593Smuzhiyun 	/*
219*4882a593Smuzhiyun 	 * num of frames in each RTT burst
220*4882a593Smuzhiyun 	 * for single side, measurement result num = frame number
221*4882a593Smuzhiyun 	 * for 2 side RTT, measurement result num  = frame number - 1
222*4882a593Smuzhiyun 	 */
223*4882a593Smuzhiyun 	uint32 num_retries_per_ftm; /* retry time for RTT measurment frame */
224*4882a593Smuzhiyun 	/* following fields are only valid for 2 side RTT */
225*4882a593Smuzhiyun 	uint32 num_retries_per_ftmr;
226*4882a593Smuzhiyun 	uint8  LCI_request;
227*4882a593Smuzhiyun 	uint8  LCR_request;
228*4882a593Smuzhiyun 	/*
229*4882a593Smuzhiyun 	* Applies to 1-sided and 2-sided RTT. Valid values will
230*4882a593Smuzhiyun 	* be 2-11 and 15 as specified by the 802.11mc std for
231*4882a593Smuzhiyun 	* the FTM parameter burst duration. In a multi-burst
232*4882a593Smuzhiyun 	* request, if responder overrides with larger value,
233*4882a593Smuzhiyun 	* the initiator will return failure. In a single-burst
234*4882a593Smuzhiyun 	* request if responder overrides with larger value,
235*4882a593Smuzhiyun 	* the initiator will sent TMR_STOP to terminate RTT
236*4882a593Smuzhiyun 	* at the end of the burst_duration it requested.
237*4882a593Smuzhiyun 	*/
238*4882a593Smuzhiyun 	uint32 burst_duration;
239*4882a593Smuzhiyun 	uint32 burst_timeout;
240*4882a593Smuzhiyun 	uint8  preamble; /* 1 - Legacy, 2 - HT, 4 - VHT */
241*4882a593Smuzhiyun 	uint8  bw;  /* 5, 10, 20, 40, 80, 160 */
242*4882a593Smuzhiyun } rtt_target_info_t;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun typedef struct rtt_goefence_target_info {
245*4882a593Smuzhiyun 	bool valid;
246*4882a593Smuzhiyun 	struct ether_addr peer_addr;
247*4882a593Smuzhiyun } rtt_geofence_target_info_t;
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun typedef struct rtt_config_params {
250*4882a593Smuzhiyun 	int8 rtt_target_cnt;
251*4882a593Smuzhiyun 	uint8 target_list_mode;
252*4882a593Smuzhiyun 	rtt_target_info_t *target_info;
253*4882a593Smuzhiyun } rtt_config_params_t;
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun typedef struct rtt_geofence_setup_status {
256*4882a593Smuzhiyun 	bool geofence_setup_inprog; /* Lock to serialize geofence setup */
257*4882a593Smuzhiyun 	struct nan_ranging_inst *rng_inst; /* Locked for this ranging instance */
258*4882a593Smuzhiyun } rtt_geofence_setup_status_t;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun typedef struct rtt_geofence_cfg {
261*4882a593Smuzhiyun 	int8 geofence_target_cnt;
262*4882a593Smuzhiyun 	int8 cur_target_idx;
263*4882a593Smuzhiyun 	rtt_geofence_target_info_t geofence_target_info[RTT_MAX_GEOFENCE_TARGET_CNT];
264*4882a593Smuzhiyun 	int geofence_rtt_interval;
265*4882a593Smuzhiyun 	int max_geofence_sessions; /* Polled from FW via IOVAR Query */
266*4882a593Smuzhiyun 	int geofence_sessions_cnt; /* No. of Geofence/Resp Sessions running currently */
267*4882a593Smuzhiyun 	rtt_geofence_setup_status_t geofence_setup_status;
268*4882a593Smuzhiyun #ifdef RTT_GEOFENCE_CONT
269*4882a593Smuzhiyun 	bool geofence_cont;
270*4882a593Smuzhiyun #endif /* RTT_GEOFENCE_CONT */
271*4882a593Smuzhiyun } rtt_geofence_cfg_t;
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun typedef struct rtt_directed_setup_status {
274*4882a593Smuzhiyun 	bool directed_na_setup_inprog; /* Lock to serialize directed setup */
275*4882a593Smuzhiyun 	struct nan_ranging_inst *rng_inst; /* Locked for this ranging instance */
276*4882a593Smuzhiyun } rtt_directed_setup_status_t;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun typedef struct rtt_directed_cfg {
279*4882a593Smuzhiyun 	int directed_sessions_cnt; /* No. of Geofence/Resp Sessions running currently */
280*4882a593Smuzhiyun 	rtt_directed_setup_status_t directed_setup_status;
281*4882a593Smuzhiyun } rtt_directed_cfg_t;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun /*
284*4882a593Smuzhiyun  * Keep Adding more reasons
285*4882a593Smuzhiyun  * going forward if needed
286*4882a593Smuzhiyun  */
287*4882a593Smuzhiyun enum rtt_schedule_reason {
288*4882a593Smuzhiyun 	RTT_SCHED_HOST_TRIGGER			= 1, /* On host command for directed RTT */
289*4882a593Smuzhiyun 	RTT_SCHED_SUB_MATCH			= 2, /* on Sub Match for svc with range req */
290*4882a593Smuzhiyun 	RTT_SCHED_DIR_TRIGGER_FAIL		= 3, /* On failure of Directed RTT Trigger */
291*4882a593Smuzhiyun 	RTT_SCHED_DP_END			= 4, /* ON NDP End event from fw */
292*4882a593Smuzhiyun 	RTT_SCHED_DP_REJECTED			= 5, /* On receving reject dp event from fw */
293*4882a593Smuzhiyun 	RTT_SCHED_RNG_RPT_DIRECTED		= 6, /* On Ranging report for directed RTT */
294*4882a593Smuzhiyun 	RTT_SCHED_RNG_TERM			= 7, /* On Range Term Indicator */
295*4882a593Smuzhiyun 	RTT_SHCED_HOST_DIRECTED_TERM		= 8, /* On host terminating directed RTT sessions */
296*4882a593Smuzhiyun 	RTT_SCHED_RNG_RPT_GEOFENCE		= 9, /* On Ranging report for geofence RTT */
297*4882a593Smuzhiyun 	RTT_SCHED_RTT_RETRY_GEOFENCE		= 10, /* On Geofence Retry */
298*4882a593Smuzhiyun 	RTT_SCHED_RNG_TERM_PEND_ROLE_CHANGE	= 11, /* On Rng Term, while pending role change */
299*4882a593Smuzhiyun 	RTT_SCHED_RNG_TERM_SUB_SVC_CANCEL	= 12, /* Due rng canc attempt, on sub cancel */
300*4882a593Smuzhiyun 	RTT_SCHED_RNG_TERM_SUB_SVC_UPD		= 13, /* Due rng canc attempt, on sub update */
301*4882a593Smuzhiyun 	RTT_SCHED_RNG_TERM_PUB_RNG_CLEAR	= 14, /* Due rng canc attempt, on pub upd/timeout */
302*4882a593Smuzhiyun 	RTT_SCHED_RNG_RESP_IND			= 15, /* Due to rng resp ind */
303*4882a593Smuzhiyun 	RTT_SCHED_RNG_DIR_EXCESS_TARGET		= 16  /* On ssn end, if excess dir tgt pending */
304*4882a593Smuzhiyun };
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun /*
307*4882a593Smuzhiyun  * Keep Adding more invalid RTT states
308*4882a593Smuzhiyun  * going forward if needed
309*4882a593Smuzhiyun  */
310*4882a593Smuzhiyun enum rtt_invalid_state {
311*4882a593Smuzhiyun 	RTT_STATE_VALID			= 0, /* RTT state is valid */
312*4882a593Smuzhiyun 	RTT_STATE_INV_REASON_NDP_EXIST	= 1 /* RTT state invalid as ndp exists */
313*4882a593Smuzhiyun };
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun typedef struct rtt_status_info {
316*4882a593Smuzhiyun 	dhd_pub_t	*dhd;
317*4882a593Smuzhiyun 	int8		status;   /* current status for the current entry */
318*4882a593Smuzhiyun 	int8		txchain; /* current device tx chain */
319*4882a593Smuzhiyun 	int		pm; /* to save current value of pm */
320*4882a593Smuzhiyun 	int8		pm_restore; /* flag to reset the old value of pm */
321*4882a593Smuzhiyun 	int8		cur_idx; /* current entry to do RTT */
322*4882a593Smuzhiyun 	int8		start_idx; /* start index for RTT */
323*4882a593Smuzhiyun 	bool		all_cancel; /* cancel all request once we got the cancel requet */
324*4882a593Smuzhiyun 	uint32		flags; /* indicate whether device is configured as initiator or target */
325*4882a593Smuzhiyun 	struct capability {
326*4882a593Smuzhiyun 		int32 proto     :8;
327*4882a593Smuzhiyun 		int32 feature   :8;
328*4882a593Smuzhiyun 		int32 preamble  :8;
329*4882a593Smuzhiyun 		int32 bw        :8;
330*4882a593Smuzhiyun 	} rtt_capa; /* rtt capability */
331*4882a593Smuzhiyun 	struct			mutex rtt_mutex;
332*4882a593Smuzhiyun 	struct			mutex geofence_mutex;
333*4882a593Smuzhiyun 	rtt_config_params_t	rtt_config;
334*4882a593Smuzhiyun 	rtt_geofence_cfg_t	geofence_cfg;
335*4882a593Smuzhiyun 	rtt_directed_cfg_t	directed_cfg;
336*4882a593Smuzhiyun 	struct work_struct	work;
337*4882a593Smuzhiyun 	struct list_head	noti_fn_list;
338*4882a593Smuzhiyun 	struct list_head	rtt_results_cache; /* store results for RTT */
339*4882a593Smuzhiyun 	int			rtt_sched_reason; /* rtt_schedule_reason: what scheduled RTT */
340*4882a593Smuzhiyun 	struct delayed_work	proxd_timeout; /* Proxd Timeout work */
341*4882a593Smuzhiyun 	struct delayed_work	rtt_retry_timer;   /* Timer for retry RTT after all targets done */
342*4882a593Smuzhiyun 	bool			rtt_sched; /* TO serialize rtt thread */
343*4882a593Smuzhiyun 	int			max_nan_rtt_sessions; /* To be Polled from FW via IOVAR Query */
344*4882a593Smuzhiyun } rtt_status_info_t;
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun typedef struct rtt_report {
347*4882a593Smuzhiyun 	struct ether_addr addr;
348*4882a593Smuzhiyun 	unsigned int burst_num; /* # of burst inside a multi-burst request */
349*4882a593Smuzhiyun 	unsigned int ftm_num; /* total RTT measurement frames attempted */
350*4882a593Smuzhiyun 	unsigned int success_num; /* total successful RTT measurement frames */
351*4882a593Smuzhiyun 	uint8  num_per_burst_peer; /* max number of FTM number per burst the peer support */
352*4882a593Smuzhiyun 	rtt_reason_t status; /* raging status */
353*4882a593Smuzhiyun 	/* in s, 11mc only, only for RTT_REASON_FAIL_BUSY_TRY_LATER, 1- 31s */
354*4882a593Smuzhiyun 	uint8 retry_after_duration;
355*4882a593Smuzhiyun 	rtt_type_t type; /* rtt type */
356*4882a593Smuzhiyun 	wifi_rssi_rtt  rssi; /* average rssi in 0.5 dB steps e.g. 143 implies -71.5 dB */
357*4882a593Smuzhiyun 	wifi_rssi_rtt  rssi_spread; /* rssi spread in 0.5 db steps e.g. 5 implies 2.5 spread */
358*4882a593Smuzhiyun 	/*
359*4882a593Smuzhiyun 	* 1-sided RTT: TX rate of RTT frame.
360*4882a593Smuzhiyun 	* 2-sided RTT: TX rate of initiator's Ack in response to FTM frame.
361*4882a593Smuzhiyun 	*/
362*4882a593Smuzhiyun 	wifi_rate_v1 tx_rate;
363*4882a593Smuzhiyun 	/*
364*4882a593Smuzhiyun 	* 1-sided RTT: TX rate of Ack from other side.
365*4882a593Smuzhiyun 	* 2-sided RTT: TX rate of FTM frame coming from responder.
366*4882a593Smuzhiyun 	*/
367*4882a593Smuzhiyun 	wifi_rate_v1 rx_rate;
368*4882a593Smuzhiyun 	wifi_timespan rtt;	/*  round trip time in 0.1 nanoseconds */
369*4882a593Smuzhiyun 	wifi_timespan rtt_sd;	/* rtt standard deviation in 0.1 nanoseconds */
370*4882a593Smuzhiyun 	wifi_timespan rtt_spread; /* difference between max and min rtt times recorded */
371*4882a593Smuzhiyun 	int distance; /* distance in cm (optional) */
372*4882a593Smuzhiyun 	int distance_sd; /* standard deviation in cm (optional) */
373*4882a593Smuzhiyun 	int distance_spread; /* difference between max and min distance recorded (optional) */
374*4882a593Smuzhiyun 	wifi_timestamp ts; /* time of the measurement (in microseconds since boot) */
375*4882a593Smuzhiyun 	int burst_duration; /* in ms, how long the FW time is to fininish one burst measurement */
376*4882a593Smuzhiyun 	int negotiated_burst_num; /* Number of bursts allowed by the responder */
377*4882a593Smuzhiyun 	bcm_tlv_t *LCI; /* LCI Report */
378*4882a593Smuzhiyun 	bcm_tlv_t *LCR; /* Location Civic Report */
379*4882a593Smuzhiyun } rtt_report_t;
380*4882a593Smuzhiyun #define RTT_REPORT_SIZE (sizeof(rtt_report_t))
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun /* rtt_results_header to maintain rtt result list per mac address */
383*4882a593Smuzhiyun typedef struct rtt_results_header {
384*4882a593Smuzhiyun 	struct ether_addr peer_mac;
385*4882a593Smuzhiyun 	uint32 result_cnt;
386*4882a593Smuzhiyun 	uint32 result_tot_len; /* sum of report_len of rtt_result */
387*4882a593Smuzhiyun 	struct list_head list;
388*4882a593Smuzhiyun 	struct list_head result_list;
389*4882a593Smuzhiyun } rtt_results_header_t;
390*4882a593Smuzhiyun struct rtt_result_detail {
391*4882a593Smuzhiyun 	uint8 num_ota_meas;
392*4882a593Smuzhiyun 	uint32 result_flags;
393*4882a593Smuzhiyun };
394*4882a593Smuzhiyun /* rtt_result to link all of rtt_report */
395*4882a593Smuzhiyun typedef struct rtt_result {
396*4882a593Smuzhiyun 	struct list_head list;
397*4882a593Smuzhiyun 	struct rtt_report report;
398*4882a593Smuzhiyun 	int32 report_len; /* total length of rtt_report */
399*4882a593Smuzhiyun 	struct rtt_result_detail rtt_detail;
400*4882a593Smuzhiyun 	int32 detail_len;
401*4882a593Smuzhiyun } rtt_result_t;
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun /* RTT Capabilities */
404*4882a593Smuzhiyun typedef struct rtt_capabilities {
405*4882a593Smuzhiyun 	uint8 rtt_one_sided_supported;  /* if 1-sided rtt data collection is supported */
406*4882a593Smuzhiyun 	uint8 rtt_ftm_supported;        /* if ftm rtt data collection is supported */
407*4882a593Smuzhiyun 	uint8 lci_support;		/* location configuration information */
408*4882a593Smuzhiyun 	uint8 lcr_support;		/* Civic Location */
409*4882a593Smuzhiyun 	uint8 preamble_support;         /* bit mask indicate what preamble is supported */
410*4882a593Smuzhiyun 	uint8 bw_support;               /* bit mask indicate what BW is supported */
411*4882a593Smuzhiyun } rtt_capabilities_t;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun /* RTT responder information */
414*4882a593Smuzhiyun typedef struct wifi_rtt_responder {
415*4882a593Smuzhiyun 	wifi_channel_info channel;   /* channel of responder */
416*4882a593Smuzhiyun 	uint8 preamble;             /* preamble supported by responder */
417*4882a593Smuzhiyun } wifi_rtt_responder_t;
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun typedef void (*dhd_rtt_compl_noti_fn)(void *ctx, void *rtt_data);
420*4882a593Smuzhiyun /* Linux wrapper to call common dhd_rtt_set_cfg */
421*4882a593Smuzhiyun int dhd_dev_rtt_set_cfg(struct net_device *dev, void *buf);
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun int dhd_dev_rtt_cancel_cfg(struct net_device *dev, struct ether_addr *mac_list, int mac_cnt);
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun int dhd_dev_rtt_register_noti_callback(struct net_device *dev, void *ctx,
426*4882a593Smuzhiyun 	dhd_rtt_compl_noti_fn noti_fn);
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun int dhd_dev_rtt_unregister_noti_callback(struct net_device *dev, dhd_rtt_compl_noti_fn noti_fn);
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun int dhd_dev_rtt_capability(struct net_device *dev, rtt_capabilities_t *capa);
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun int dhd_dev_rtt_avail_channel(struct net_device *dev, wifi_channel_info *channel_info);
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun int dhd_dev_rtt_enable_responder(struct net_device *dev, wifi_channel_info *channel_info);
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun int dhd_dev_rtt_cancel_responder(struct net_device *dev);
437*4882a593Smuzhiyun /* export to upper layer */
438*4882a593Smuzhiyun chanspec_t dhd_rtt_convert_to_chspec(wifi_channel_info channel);
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun int dhd_rtt_idx_to_burst_duration(uint idx);
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun int dhd_rtt_set_cfg(dhd_pub_t *dhd, rtt_config_params_t *params);
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun #ifdef WL_NAN
445*4882a593Smuzhiyun void dhd_rtt_initialize_geofence_cfg(dhd_pub_t *dhd);
446*4882a593Smuzhiyun #ifdef RTT_GEOFENCE_CONT
447*4882a593Smuzhiyun void dhd_rtt_set_geofence_cont_ind(dhd_pub_t *dhd, bool geofence_cont);
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun void dhd_rtt_get_geofence_cont_ind(dhd_pub_t *dhd, bool* geofence_cont);
450*4882a593Smuzhiyun #endif /* RTT_GEOFENCE_CONT */
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun #ifdef RTT_GEOFENCE_INTERVAL
453*4882a593Smuzhiyun void dhd_rtt_set_geofence_rtt_interval(dhd_pub_t *dhd, int interval);
454*4882a593Smuzhiyun #endif /* RTT_GEOFENCE_INTERVAL */
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun int dhd_rtt_get_geofence_max_sessions(dhd_pub_t *dhd);
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun bool dhd_rtt_geofence_sessions_maxed_out(dhd_pub_t *dhd);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun int dhd_rtt_get_geofence_sessions_cnt(dhd_pub_t *dhd);
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun int dhd_rtt_update_geofence_sessions_cnt(dhd_pub_t *dhd, bool incr,
463*4882a593Smuzhiyun 	struct ether_addr *peer_addr);
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun int8 dhd_rtt_get_geofence_target_cnt(dhd_pub_t *dhd);
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun rtt_geofence_target_info_t* dhd_rtt_get_geofence_target_head(dhd_pub_t *dhd);
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun rtt_geofence_target_info_t* dhd_rtt_get_geofence_current_target(dhd_pub_t *dhd);
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun rtt_geofence_target_info_t*
472*4882a593Smuzhiyun dhd_rtt_get_geofence_target(dhd_pub_t *dhd, struct ether_addr* peer_addr,
473*4882a593Smuzhiyun 	int8 *index);
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun int dhd_rtt_add_geofence_target(dhd_pub_t *dhd, rtt_geofence_target_info_t  *target);
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun int dhd_rtt_remove_geofence_target(dhd_pub_t *dhd, struct ether_addr *peer_addr);
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun int dhd_rtt_delete_geofence_target_list(dhd_pub_t *dhd);
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun int dhd_rtt_delete_nan_session(dhd_pub_t *dhd);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun bool dhd_rtt_nan_is_directed_setup_in_prog(dhd_pub_t *dhd);
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun bool dhd_rtt_nan_is_directed_setup_in_prog_with_peer(dhd_pub_t *dhd,
486*4882a593Smuzhiyun 	struct ether_addr *peer);
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun void dhd_rtt_nan_update_directed_setup_inprog(dhd_pub_t *dhd,
489*4882a593Smuzhiyun 	struct nan_ranging_inst *rng_inst, bool inprog);
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun bool dhd_rtt_nan_directed_sessions_allowed(dhd_pub_t *dhd);
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun bool dhd_rtt_nan_all_directed_sessions_triggered(dhd_pub_t *dhd);
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun void dhd_rtt_nan_update_directed_sessions_cnt(dhd_pub_t *dhd, bool incr);
496*4882a593Smuzhiyun #endif /* WL_NAN */
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun uint8 dhd_rtt_invalid_states(struct net_device *ndev, struct ether_addr *peer_addr);
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun int8 dhd_rtt_get_cur_target_idx(dhd_pub_t *dhd);
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun int8 dhd_rtt_set_next_target_idx(dhd_pub_t *dhd, int start_idx);
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun void dhd_rtt_schedule_rtt_work_thread(dhd_pub_t *dhd, int sched_reason);
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun int dhd_rtt_stop(dhd_pub_t *dhd, struct ether_addr *mac_list, int mac_cnt);
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun int dhd_rtt_register_noti_callback(dhd_pub_t *dhd, void *ctx, dhd_rtt_compl_noti_fn noti_fn);
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun int dhd_rtt_unregister_noti_callback(dhd_pub_t *dhd, dhd_rtt_compl_noti_fn noti_fn);
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun int dhd_rtt_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data);
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun int dhd_rtt_capability(dhd_pub_t *dhd, rtt_capabilities_t *capa);
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun int dhd_rtt_avail_channel(dhd_pub_t *dhd, wifi_channel_info *channel_info);
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun int dhd_rtt_enable_responder(dhd_pub_t *dhd, wifi_channel_info *channel_info);
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun int dhd_rtt_cancel_responder(dhd_pub_t *dhd);
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun int dhd_rtt_attach(dhd_pub_t *dhd);
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun int dhd_rtt_detach(dhd_pub_t *dhd);
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun int dhd_rtt_init(dhd_pub_t *dhd);
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun int dhd_rtt_deinit(dhd_pub_t *dhd);
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun #ifdef WL_CFG80211
531*4882a593Smuzhiyun #ifdef WL_NAN
532*4882a593Smuzhiyun int dhd_rtt_handle_nan_rtt_session_end(dhd_pub_t *dhd,
533*4882a593Smuzhiyun 	struct ether_addr *peer);
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun void dhd_rtt_move_geofence_cur_target_idx_to_next(dhd_pub_t *dhd);
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun int8 dhd_rtt_get_geofence_cur_target_idx(dhd_pub_t *dhd);
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun void dhd_rtt_set_geofence_cur_target_idx(dhd_pub_t *dhd, int8 idx);
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun rtt_geofence_setup_status_t* dhd_rtt_get_geofence_setup_status(dhd_pub_t *dhd);
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun bool dhd_rtt_is_geofence_setup_inprog(dhd_pub_t *dhd);
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun bool dhd_rtt_is_geofence_setup_inprog_with_peer(dhd_pub_t *dhd,
546*4882a593Smuzhiyun 	struct ether_addr *peer_addr);
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun void dhd_rtt_set_geofence_setup_status(dhd_pub_t *dhd, bool inprog,
549*4882a593Smuzhiyun 	struct ether_addr *peer_addr);
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun int dhd_rtt_get_max_nan_rtt_sessions_supported(dhd_pub_t *dhd);
552*4882a593Smuzhiyun #endif /* WL_NAN */
553*4882a593Smuzhiyun #endif /* WL_CFG80211 */
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun #endif /* __DHD_RTT_H__ */
556