/* SPDX-License-Identifier: GPL-2.0 */ 
 | 
/* 
 | 
 * Broadcom Dongle Host Driver (DHD), RTT 
 | 
 * 
 | 
 * Copyright (C) 1999-2017, Broadcom Corporation 
 | 
 *  
 | 
 *      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. 
 | 
 * 
 | 
 * 
 | 
 * <<Broadcom-WL-IPTag/Open:>> 
 | 
 * 
 | 
 * $Id$ 
 | 
 */ 
 | 
#ifndef __DHD_RTT_H__ 
 | 
#define __DHD_RTT_H__ 
 | 
  
 | 
#include "dngl_stats.h" 
 | 
  
 | 
#define RTT_MAX_TARGET_CNT 50 
 | 
#define RTT_MAX_FRAME_CNT 25 
 | 
#define RTT_MAX_RETRY_CNT 10 
 | 
#define DEFAULT_FTM_CNT 6 
 | 
#define DEFAULT_RETRY_CNT 6 
 | 
#define DEFAULT_FTM_FREQ 5180 
 | 
#define DEFAULT_FTM_CNTR_FREQ0 5210 
 | 
  
 | 
#define TARGET_INFO_SIZE(count) (sizeof(rtt_target_info_t) * count) 
 | 
  
 | 
#define TARGET_TYPE(target) (target->type) 
 | 
  
 | 
#ifndef BIT 
 | 
#define BIT(x) (1 << (x)) 
 | 
#endif 
 | 
  
 | 
/* DSSS, CCK and 802.11n rates in [500kbps] units */ 
 | 
#define WL_MAXRATE    108    /* in 500kbps units */ 
 | 
#define WL_RATE_1M    2    /* in 500kbps units */ 
 | 
#define WL_RATE_2M    4    /* in 500kbps units */ 
 | 
#define WL_RATE_5M5    11    /* in 500kbps units */ 
 | 
#define WL_RATE_11M    22    /* in 500kbps units */ 
 | 
#define WL_RATE_6M    12    /* in 500kbps units */ 
 | 
#define WL_RATE_9M    18    /* in 500kbps units */ 
 | 
#define WL_RATE_12M    24    /* in 500kbps units */ 
 | 
#define WL_RATE_18M    36    /* in 500kbps units */ 
 | 
#define WL_RATE_24M    48    /* in 500kbps units */ 
 | 
#define WL_RATE_36M    72    /* in 500kbps units */ 
 | 
#define WL_RATE_48M    96    /* in 500kbps units */ 
 | 
#define WL_RATE_54M    108    /* in 500kbps units */ 
 | 
#define GET_RTTSTATE(dhd) ((rtt_status_info_t *)dhd->rtt_state) 
 | 
  
 | 
enum rtt_role { 
 | 
    RTT_INITIATOR = 0, 
 | 
    RTT_TARGET = 1 
 | 
}; 
 | 
enum rtt_status { 
 | 
    RTT_STOPPED = 0, 
 | 
    RTT_STARTED = 1, 
 | 
    RTT_ENABLED = 2 
 | 
}; 
 | 
typedef int64_t wifi_timestamp; /* In microseconds (us) */ 
 | 
typedef int64_t wifi_timespan; 
 | 
typedef int32 wifi_rssi_rtt; 
 | 
  
 | 
typedef enum { 
 | 
    RTT_INVALID, 
 | 
    RTT_ONE_WAY, 
 | 
    RTT_TWO_WAY, 
 | 
    RTT_AUTO 
 | 
} rtt_type_t; 
 | 
  
 | 
typedef enum { 
 | 
    RTT_PEER_STA, 
 | 
    RTT_PEER_AP, 
 | 
    RTT_PEER_P2P, 
 | 
    RTT_PEER_NAN, 
 | 
    RTT_PEER_INVALID 
 | 
} rtt_peer_type_t; 
 | 
  
 | 
typedef enum rtt_reason { 
 | 
    RTT_REASON_SUCCESS, 
 | 
    RTT_REASON_FAILURE, 
 | 
    RTT_REASON_FAIL_NO_RSP, 
 | 
    RTT_REASON_FAIL_INVALID_TS, /* Invalid timestamp */ 
 | 
    RTT_REASON_FAIL_PROTOCOL, /* 11mc protocol failed */ 
 | 
    RTT_REASON_FAIL_REJECTED, 
 | 
    RTT_REASON_FAIL_NOT_SCHEDULED_YET, 
 | 
    RTT_REASON_FAIL_SCHEDULE, /* schedule failed */ 
 | 
    RTT_REASON_FAIL_TM_TIMEOUT, 
 | 
    RTT_REASON_FAIL_AP_ON_DIFF_CHANNEL, 
 | 
    RTT_REASON_FAIL_NO_CAPABILITY, 
 | 
    RTT_REASON_FAIL_BUSY_TRY_LATER, 
 | 
    RTT_REASON_ABORTED 
 | 
} rtt_reason_t; 
 | 
  
 | 
enum { 
 | 
    RTT_CAP_ONE_WAY     = BIT(0), 
 | 
    /* IEEE802.11mc */ 
 | 
    RTT_CAP_FTM_WAY  = BIT(1) 
 | 
}; 
 | 
  
 | 
enum { 
 | 
    RTT_FEATURE_LCI = BIT(0), 
 | 
    RTT_FEATURE_LCR = BIT(1), 
 | 
    RTT_FEATURE_PREAMBLE = BIT(2), 
 | 
    RTT_FEATURE_BW = BIT(3) 
 | 
}; 
 | 
  
 | 
enum { 
 | 
    RTT_PREAMBLE_LEGACY = BIT(0), 
 | 
    RTT_PREAMBLE_HT = BIT(1), 
 | 
    RTT_PREAMBLE_VHT = BIT(2) 
 | 
}; 
 | 
  
 | 
  
 | 
enum { 
 | 
    RTT_BW_5 = BIT(0), 
 | 
    RTT_BW_10 = BIT(1), 
 | 
    RTT_BW_20 = BIT(2), 
 | 
    RTT_BW_40 = BIT(3), 
 | 
    RTT_BW_80 = BIT(4), 
 | 
    RTT_BW_160 = BIT(5) 
 | 
}; 
 | 
#define FTM_MAX_NUM_BURST_EXP    14 
 | 
#define HAS_11MC_CAP(cap) (cap & RTT_CAP_FTM_WAY) 
 | 
#define HAS_ONEWAY_CAP(cap) (cap & RTT_CAP_ONE_WAY) 
 | 
#define HAS_RTT_CAP(cap) (HAS_ONEWAY_CAP(cap) || HAS_11MC_CAP(cap)) 
 | 
  
 | 
typedef struct wifi_channel_info { 
 | 
    wifi_channel_width_t width; 
 | 
    wifi_channel center_freq; /* primary 20 MHz channel */ 
 | 
    wifi_channel center_freq0; /* center freq (MHz) first segment */ 
 | 
    wifi_channel center_freq1; /* center freq (MHz) second segment valid for 80 + 80 */ 
 | 
} wifi_channel_info_t; 
 | 
  
 | 
typedef struct wifi_rate { 
 | 
    uint32 preamble :3; /* 0: OFDM, 1: CCK, 2 : HT, 3: VHT, 4..7 reserved */ 
 | 
    uint32 nss        :2; /* 1 : 1x1, 2: 2x2, 3: 3x3, 4: 4x4 */ 
 | 
    uint32 bw        :3; /* 0: 20Mhz, 1: 40Mhz, 2: 80Mhz, 3: 160Mhz */ 
 | 
    /* OFDM/CCK rate code would be as per IEEE std in the unit of 0.5 mb 
 | 
    * HT/VHT it would be mcs index 
 | 
    */ 
 | 
    uint32 rateMcsIdx :8; 
 | 
    uint32 reserved :16; /* reserved */ 
 | 
    uint32 bitrate;    /* unit of 100 Kbps */ 
 | 
} wifi_rate_t; 
 | 
  
 | 
typedef struct rtt_target_info { 
 | 
    struct ether_addr addr; 
 | 
    rtt_type_t type; /* rtt_type */ 
 | 
    rtt_peer_type_t peer; /* peer type */ 
 | 
    wifi_channel_info_t channel; /* channel information */ 
 | 
    chanspec_t chanspec; /* chanspec for channel */ 
 | 
    bool    disable; /* disable for RTT measurement */ 
 | 
    /* 
 | 
    * Time interval between bursts (units: 100 ms). 
 | 
    * Applies to 1-sided and 2-sided RTT multi-burst requests. 
 | 
    * Range: 0-31, 0: no preference by initiator (2-sided RTT) 
 | 
    */ 
 | 
    uint32    burst_period; 
 | 
    /* 
 | 
    * Total number of RTT bursts to be executed. It will be 
 | 
    * specified in the same way as the parameter "Number of 
 | 
    * Burst Exponent" found in the FTM frame format. It 
 | 
    * applies to both: 1-sided RTT and 2-sided RTT. Valid 
 | 
    * values are 0 to 15 as defined in 802.11mc std. 
 | 
    * 0 means single shot 
 | 
    * The implication of this parameter on the maximum 
 | 
    * number of RTT results is the following: 
 | 
    * for 1-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst) 
 | 
    * for 2-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst - 1) 
 | 
    */ 
 | 
    uint16 num_burst; 
 | 
    /* 
 | 
    * num of frames per burst. 
 | 
    * Minimum value = 1, Maximum value = 31 
 | 
    * For 2-sided this equals the number of FTM frames 
 | 
    * to be attempted in a single burst. This also 
 | 
    * equals the number of FTM frames that the 
 | 
    * initiator will request that the responder send 
 | 
    * in a single frame 
 | 
    */ 
 | 
    uint32 num_frames_per_burst; 
 | 
    /* num of frames in each RTT burst 
 | 
     * for single side, measurement result num = frame number 
 | 
     * for 2 side RTT, measurement result num  = frame number - 1 
 | 
     */ 
 | 
    uint32 num_retries_per_ftm; /* retry time for RTT measurment frame */ 
 | 
    /* following fields are only valid for 2 side RTT */ 
 | 
    uint32 num_retries_per_ftmr; 
 | 
    uint8  LCI_request; 
 | 
    uint8  LCR_request; 
 | 
    /* 
 | 
    * Applies to 1-sided and 2-sided RTT. Valid values will 
 | 
    * be 2-11 and 15 as specified by the 802.11mc std for 
 | 
    * the FTM parameter burst duration. In a multi-burst 
 | 
    * request, if responder overrides with larger value, 
 | 
    * the initiator will return failure. In a single-burst 
 | 
    * request if responder overrides with larger value, 
 | 
    * the initiator will sent TMR_STOP to terminate RTT 
 | 
    * at the end of the burst_duration it requested. 
 | 
    */ 
 | 
    uint32 burst_duration; 
 | 
    uint8  preamble; /* 1 - Legacy, 2 - HT, 4 - VHT */ 
 | 
    uint8  bw;  /* 5, 10, 20, 40, 80, 160 */ 
 | 
} rtt_target_info_t; 
 | 
  
 | 
typedef struct rtt_config_params { 
 | 
    int8 rtt_target_cnt; 
 | 
    rtt_target_info_t *target_info; 
 | 
} rtt_config_params_t; 
 | 
  
 | 
typedef struct rtt_status_info { 
 | 
    dhd_pub_t *dhd; 
 | 
    int8 status;   /* current status for the current entry */ 
 | 
    int8 txchain; /* current device tx chain */ 
 | 
    int8 mpc; /* indicate we change mpc mode */ 
 | 
    int pm; /* to save current value of pm */ 
 | 
    int8 pm_restore; /* flag to reset the old value of pm */ 
 | 
    int8 cur_idx; /* current entry to do RTT */ 
 | 
    bool all_cancel; /* cancel all request once we got the cancel requet */ 
 | 
    uint32 flags; /* indicate whether device is configured as initiator or target */ 
 | 
    struct capability { 
 | 
        int32 proto     :8; 
 | 
        int32 feature   :8; 
 | 
        int32 preamble  :8; 
 | 
        int32 bw        :8; 
 | 
    } rtt_capa; /* rtt capability */ 
 | 
    struct mutex rtt_mutex; 
 | 
    rtt_config_params_t rtt_config; 
 | 
    struct work_struct work; 
 | 
    struct list_head noti_fn_list; 
 | 
    struct list_head rtt_results_cache; /* store results for RTT */ 
 | 
} rtt_status_info_t; 
 | 
  
 | 
typedef struct rtt_report { 
 | 
    struct ether_addr addr; 
 | 
    unsigned int burst_num; /* # of burst inside a multi-burst request */ 
 | 
    unsigned int ftm_num; /* total RTT measurement frames attempted */ 
 | 
    unsigned int success_num; /* total successful RTT measurement frames */ 
 | 
    uint8  num_per_burst_peer; /* max number of FTM number per burst the peer support */ 
 | 
    rtt_reason_t status; /* raging status */ 
 | 
    /* in s, 11mc only, only for RTT_REASON_FAIL_BUSY_TRY_LATER, 1- 31s */ 
 | 
    uint8 retry_after_duration; 
 | 
    rtt_type_t type; /* rtt type */ 
 | 
    wifi_rssi_rtt  rssi; /* average rssi in 0.5 dB steps e.g. 143 implies -71.5 dB */ 
 | 
    wifi_rssi_rtt  rssi_spread; /* rssi spread in 0.5 db steps e.g. 5 implies 2.5 spread */ 
 | 
    /* 
 | 
    * 1-sided RTT: TX rate of RTT frame. 
 | 
    * 2-sided RTT: TX rate of initiator's Ack in response to FTM frame. 
 | 
    */ 
 | 
    wifi_rate_t tx_rate; 
 | 
    /* 
 | 
    * 1-sided RTT: TX rate of Ack from other side. 
 | 
    * 2-sided RTT: TX rate of FTM frame coming from responder. 
 | 
    */ 
 | 
    wifi_rate_t rx_rate; 
 | 
    wifi_timespan rtt;    /*  round trip time in 0.1 nanoseconds */ 
 | 
    wifi_timespan rtt_sd;    /* rtt standard deviation in 0.1 nanoseconds */ 
 | 
    wifi_timespan rtt_spread; /* difference between max and min rtt times recorded */ 
 | 
    int distance; /* distance in cm (optional) */ 
 | 
    int distance_sd; /* standard deviation in cm (optional) */ 
 | 
    int distance_spread; /* difference between max and min distance recorded (optional) */ 
 | 
    wifi_timestamp ts; /* time of the measurement (in microseconds since boot) */ 
 | 
    int burst_duration; /* in ms, how long the FW time is to fininish one burst measurement */ 
 | 
    int negotiated_burst_num; /* Number of bursts allowed by the responder */ 
 | 
    bcm_tlv_t *LCI; /* LCI Report */ 
 | 
    bcm_tlv_t *LCR; /* Location Civic Report */ 
 | 
} rtt_report_t; 
 | 
#define RTT_REPORT_SIZE (sizeof(rtt_report_t)) 
 | 
  
 | 
/* rtt_results_header to maintain rtt result list per mac address */ 
 | 
typedef struct rtt_results_header { 
 | 
    struct ether_addr peer_mac; 
 | 
    uint32 result_cnt; 
 | 
    uint32 result_tot_len; /* sum of report_len of rtt_result */ 
 | 
    struct list_head list; 
 | 
    struct list_head result_list; 
 | 
} rtt_results_header_t; 
 | 
  
 | 
/* rtt_result to link all of rtt_report */ 
 | 
typedef struct rtt_result { 
 | 
    struct list_head list; 
 | 
    struct rtt_report report; 
 | 
    int32 report_len; /* total length of rtt_report */ 
 | 
} rtt_result_t; 
 | 
  
 | 
/* RTT Capabilities */ 
 | 
typedef struct rtt_capabilities { 
 | 
    uint8 rtt_one_sided_supported;  /* if 1-sided rtt data collection is supported */ 
 | 
    uint8 rtt_ftm_supported;        /* if ftm rtt data collection is supported */ 
 | 
    uint8 lci_support;        /* location configuration information */ 
 | 
    uint8 lcr_support;        /* Civic Location */ 
 | 
    uint8 preamble_support;         /* bit mask indicate what preamble is supported */ 
 | 
    uint8 bw_support;               /* bit mask indicate what BW is supported */ 
 | 
} rtt_capabilities_t; 
 | 
  
 | 
  
 | 
/* RTT responder information */ 
 | 
typedef struct wifi_rtt_responder { 
 | 
    wifi_channel_info channel;   /* channel of responder */ 
 | 
    uint8 preamble;             /* preamble supported by responder */ 
 | 
} wifi_rtt_responder_t; 
 | 
  
 | 
typedef void (*dhd_rtt_compl_noti_fn)(void *ctx, void *rtt_data); 
 | 
/* Linux wrapper to call common dhd_rtt_set_cfg */ 
 | 
int 
 | 
dhd_dev_rtt_set_cfg(struct net_device *dev, void *buf); 
 | 
  
 | 
int 
 | 
dhd_dev_rtt_cancel_cfg(struct net_device *dev, struct ether_addr *mac_list, int mac_cnt); 
 | 
  
 | 
int 
 | 
dhd_dev_rtt_register_noti_callback(struct net_device *dev, void *ctx, 
 | 
    dhd_rtt_compl_noti_fn noti_fn); 
 | 
  
 | 
int 
 | 
dhd_dev_rtt_unregister_noti_callback(struct net_device *dev, dhd_rtt_compl_noti_fn noti_fn); 
 | 
  
 | 
int 
 | 
dhd_dev_rtt_capability(struct net_device *dev, rtt_capabilities_t *capa); 
 | 
  
 | 
#ifdef WL_CFG80211 
 | 
int 
 | 
dhd_dev_rtt_avail_channel(struct net_device *dev, wifi_channel_info *channel_info); 
 | 
#endif /* WL_CFG80211 */ 
 | 
  
 | 
int 
 | 
dhd_dev_rtt_enable_responder(struct net_device *dev, wifi_channel_info *channel_info); 
 | 
  
 | 
int 
 | 
dhd_dev_rtt_cancel_responder(struct net_device *dev); 
 | 
/* export to upper layer */ 
 | 
chanspec_t 
 | 
dhd_rtt_convert_to_chspec(wifi_channel_info_t channel); 
 | 
  
 | 
int 
 | 
dhd_rtt_idx_to_burst_duration(uint idx); 
 | 
  
 | 
int 
 | 
dhd_rtt_set_cfg(dhd_pub_t *dhd, rtt_config_params_t *params); 
 | 
  
 | 
int 
 | 
dhd_rtt_stop(dhd_pub_t *dhd, struct ether_addr *mac_list, int mac_cnt); 
 | 
  
 | 
  
 | 
int 
 | 
dhd_rtt_register_noti_callback(dhd_pub_t *dhd, void *ctx, dhd_rtt_compl_noti_fn noti_fn); 
 | 
  
 | 
int 
 | 
dhd_rtt_unregister_noti_callback(dhd_pub_t *dhd, dhd_rtt_compl_noti_fn noti_fn); 
 | 
  
 | 
int 
 | 
dhd_rtt_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data); 
 | 
  
 | 
int 
 | 
dhd_rtt_capability(dhd_pub_t *dhd, rtt_capabilities_t *capa); 
 | 
  
 | 
int 
 | 
dhd_rtt_avail_channel(dhd_pub_t *dhd, wifi_channel_info *channel_info); 
 | 
  
 | 
int 
 | 
dhd_rtt_enable_responder(dhd_pub_t *dhd, wifi_channel_info *channel_info); 
 | 
  
 | 
int 
 | 
dhd_rtt_cancel_responder(dhd_pub_t *dhd); 
 | 
  
 | 
int 
 | 
dhd_rtt_init(dhd_pub_t *dhd); 
 | 
  
 | 
int 
 | 
dhd_rtt_deinit(dhd_pub_t *dhd); 
 | 
#endif /* __DHD_RTT_H__ */ 
 |