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