.. | .. |
---|
1 | | -/* SPDX-License-Identifier: GPL-2.0 */ |
---|
2 | 1 | /* |
---|
3 | 2 | * Broadcom Dongle Host Driver (DHD), RTT |
---|
4 | 3 | * |
---|
5 | | - * Copyright (C) 1999-2019, Broadcom Corporation |
---|
6 | | - * |
---|
| 4 | + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation |
---|
| 5 | + * |
---|
| 6 | + * Copyright (C) 1999-2017, Broadcom Corporation |
---|
| 7 | + * |
---|
7 | 8 | * Unless you and Broadcom execute a separate written software license |
---|
8 | 9 | * agreement governing use of this software, this software is licensed to you |
---|
9 | 10 | * under the terms of the GNU General Public License version 2 (the "GPL"), |
---|
10 | 11 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
---|
11 | 12 | * following added to such license: |
---|
12 | | - * |
---|
| 13 | + * |
---|
13 | 14 | * As a special exception, the copyright holders of this software give you |
---|
14 | 15 | * permission to link this software with independent modules, and to copy and |
---|
15 | 16 | * distribute the resulting executable under terms of your choice, provided that |
---|
.. | .. |
---|
17 | 18 | * the license of that module. An independent module is a module which is not |
---|
18 | 19 | * derived from this software. The special exception does not apply to any |
---|
19 | 20 | * modifications of the software. |
---|
20 | | - * |
---|
| 21 | + * |
---|
21 | 22 | * Notwithstanding the above, under no circumstances may you combine this |
---|
22 | 23 | * software in any way with any other Broadcom software provided under a license |
---|
23 | 24 | * other than the GPL, without Broadcom's express prior written consent. |
---|
24 | 25 | * |
---|
25 | | - * $Id: dhd_rtt.c 674349 2017-10-19 07:59:24Z $ |
---|
| 26 | + * |
---|
| 27 | + * <<Broadcom-WL-IPTag/Open:>> |
---|
| 28 | + * |
---|
| 29 | + * $Id$ |
---|
26 | 30 | */ |
---|
27 | 31 | #include <typedefs.h> |
---|
28 | 32 | #include <osl.h> |
---|
.. | .. |
---|
38 | 42 | #include <linux/sort.h> |
---|
39 | 43 | #include <dngl_stats.h> |
---|
40 | 44 | #include <wlioctl.h> |
---|
| 45 | +#include <bcmwifi_rspec.h> |
---|
41 | 46 | |
---|
42 | | -#include <proto/bcmevent.h> |
---|
| 47 | +#include <bcmevent.h> |
---|
43 | 48 | #include <dhd.h> |
---|
| 49 | +#include <dhd_linux.h> |
---|
44 | 50 | #include <dhd_rtt.h> |
---|
45 | 51 | #include <dhd_dbg.h> |
---|
46 | | -#define GET_RTTSTATE(dhd) ((rtt_status_info_t *)dhd->rtt_state) |
---|
| 52 | +#include <dhd_bus.h> |
---|
| 53 | +#include <wldev_common.h> |
---|
| 54 | +#ifdef WL_CFG80211 |
---|
| 55 | +#include <wl_cfg80211.h> |
---|
| 56 | +#endif /* WL_CFG80211 */ |
---|
| 57 | +#ifdef WL_NAN |
---|
| 58 | +#include <wl_cfgnan.h> |
---|
| 59 | +#endif /* WL_NAN */ |
---|
| 60 | + |
---|
47 | 61 | static DEFINE_SPINLOCK(noti_list_lock); |
---|
| 62 | +#ifndef NULL_CHECK |
---|
48 | 63 | #define NULL_CHECK(p, s, err) \ |
---|
49 | 64 | do { \ |
---|
50 | 65 | if (!(p)) { \ |
---|
.. | .. |
---|
53 | 68 | return err; \ |
---|
54 | 69 | } \ |
---|
55 | 70 | } while (0) |
---|
| 71 | +#endif // endif |
---|
56 | 72 | |
---|
57 | | -#define RTT_IS_ENABLED(rtt_status) (rtt_status->status == RTT_ENABLED) |
---|
58 | | -#define RTT_IS_STOPPED(rtt_status) (rtt_status->status == RTT_STOPPED) |
---|
59 | 73 | #define TIMESPEC_TO_US(ts) (((uint64)(ts).tv_sec * USEC_PER_SEC) + \ |
---|
60 | 74 | (ts).tv_nsec / NSEC_PER_USEC) |
---|
| 75 | + |
---|
| 76 | +#undef DHD_RTT_MEM |
---|
| 77 | +#undef DHD_RTT_ERR |
---|
| 78 | +#define DHD_RTT_MEM DHD_LOG_MEM |
---|
| 79 | +#define DHD_RTT_ERR DHD_ERROR |
---|
61 | 80 | |
---|
62 | 81 | #define FTM_IOC_BUFSZ 2048 /* ioc buffsize for our module (> BCM_XTLV_HDR_SIZE) */ |
---|
63 | 82 | #define FTM_AVAIL_MAX_SLOTS 32 |
---|
.. | .. |
---|
66 | 85 | #define FTM_DEFAULT_SESSION 1 |
---|
67 | 86 | #define FTM_BURST_TIMEOUT_UNIT 250 /* 250 ns */ |
---|
68 | 87 | #define FTM_INVALID -1 |
---|
69 | | -#define FTM_DEFAULT_CNT_20M 12 |
---|
70 | | -#define FTM_DEFAULT_CNT_40M 10 |
---|
71 | | -#define FTM_DEFAULT_CNT_80M 5 |
---|
| 88 | +#define FTM_DEFAULT_CNT_20M 24u |
---|
| 89 | +#define FTM_DEFAULT_CNT_40M 16u |
---|
| 90 | +#define FTM_DEFAULT_CNT_80M 11u |
---|
| 91 | +/* To handle congestion env, set max dur/timeout */ |
---|
| 92 | +#define FTM_MAX_BURST_DUR_TMO_MS 128u |
---|
72 | 93 | |
---|
73 | 94 | /* convenience macros */ |
---|
74 | 95 | #define FTM_TU2MICRO(_tu) ((uint64)(_tu) << 10) |
---|
.. | .. |
---|
84 | 105 | |
---|
85 | 106 | /* broadcom specific set to have more accurate data */ |
---|
86 | 107 | #define ENABLE_VHT_ACK |
---|
| 108 | +#define CH_MIN_5G_CHANNEL 34 |
---|
| 109 | + |
---|
| 110 | +/* CUR ETH became obsolete with this major version onwards */ |
---|
| 111 | +#define RTT_IOV_CUR_ETH_OBSOLETE 12 |
---|
| 112 | + |
---|
| 113 | +/* PROXD TIMEOUT */ |
---|
| 114 | +#define DHD_RTT_TIMER_INTERVAL_MS 5000u |
---|
| 115 | +#define DHD_NAN_RTT_TIMER_INTERVAL_MS 10000u |
---|
87 | 116 | |
---|
88 | 117 | struct rtt_noti_callback { |
---|
89 | 118 | struct list_head list; |
---|
.. | .. |
---|
91 | 120 | dhd_rtt_compl_noti_fn noti_fn; |
---|
92 | 121 | }; |
---|
93 | 122 | |
---|
94 | | -typedef struct rtt_status_info { |
---|
95 | | - dhd_pub_t *dhd; |
---|
96 | | - int8 status; /* current status for the current entry */ |
---|
97 | | - int8 txchain; /* current device tx chain */ |
---|
98 | | - int8 mpc; /* indicate we change mpc mode */ |
---|
99 | | - int8 cur_idx; /* current entry to do RTT */ |
---|
100 | | - bool all_cancel; /* cancel all request once we got the cancel requet */ |
---|
101 | | - struct capability { |
---|
102 | | - int32 proto :8; |
---|
103 | | - int32 feature :8; |
---|
104 | | - int32 preamble :8; |
---|
105 | | - int32 bw :8; |
---|
106 | | - } rtt_capa; /* rtt capability */ |
---|
107 | | - struct mutex rtt_mutex; |
---|
108 | | - rtt_config_params_t rtt_config; |
---|
109 | | - struct work_struct work; |
---|
110 | | - struct list_head noti_fn_list; |
---|
111 | | - struct list_head rtt_results_cache; /* store results for RTT */ |
---|
112 | | -} rtt_status_info_t; |
---|
113 | | - |
---|
114 | 123 | /* bitmask indicating which command groups; */ |
---|
115 | 124 | typedef enum { |
---|
116 | 125 | FTM_SUBCMD_FLAG_METHOD = 0x01, /* FTM method command */ |
---|
117 | | - FTM_SUBCMD_FLAG_SESSION = 0x02, /* FTM session command */ |
---|
| 126 | + FTM_SUBCMD_FLAG_SESSION = 0x02, /* FTM session command */ |
---|
118 | 127 | FTM_SUBCMD_FLAG_ALL = FTM_SUBCMD_FLAG_METHOD | FTM_SUBCMD_FLAG_SESSION |
---|
119 | 128 | } ftm_subcmd_flag_t; |
---|
120 | 129 | |
---|
.. | .. |
---|
125 | 134 | FTM_CONFIG_CAT_AVAIL = 3, /* 'config avail' */ |
---|
126 | 135 | } ftm_config_category_t; |
---|
127 | 136 | |
---|
128 | | - |
---|
129 | 137 | typedef struct ftm_subcmd_info { |
---|
130 | 138 | int16 version; /* FTM version (optional) */ |
---|
131 | 139 | char *name; /* cmd-name string as cmdline input */ |
---|
.. | .. |
---|
134 | 142 | ftm_subcmd_flag_t cmdflag; /* CMD flag (optional) */ |
---|
135 | 143 | } ftm_subcmd_info_t; |
---|
136 | 144 | |
---|
137 | | - |
---|
138 | 145 | typedef struct ftm_config_options_info { |
---|
139 | | - uint32 flags; /* wl_proxd_flags_t/wl_proxd_session_flags_t */ |
---|
| 146 | + uint32 flags; /* wl_proxd_flags_t/wl_proxd_session_flags_t */ |
---|
140 | 147 | bool enable; |
---|
141 | 148 | } ftm_config_options_info_t; |
---|
142 | 149 | |
---|
.. | .. |
---|
149 | 156 | uint32 data32; |
---|
150 | 157 | uint16 data16; |
---|
151 | 158 | uint8 data8; |
---|
| 159 | + uint32 event_mask; |
---|
152 | 160 | }; |
---|
153 | 161 | } ftm_config_param_info_t; |
---|
154 | 162 | |
---|
155 | 163 | /* |
---|
156 | 164 | * definition for id-string mapping. |
---|
157 | | -* This is used to map an id (can be cmd-id, tlv-id, ....) to a text-string |
---|
158 | | -* for debug-display or cmd-log-display |
---|
| 165 | +* This is used to map an id (can be cmd-id, tlv-id, ....) to a text-string |
---|
| 166 | +* for debug-display or cmd-log-display |
---|
159 | 167 | */ |
---|
160 | 168 | typedef struct ftm_strmap_entry { |
---|
161 | 169 | int32 id; |
---|
162 | 170 | char *text; |
---|
163 | 171 | } ftm_strmap_entry_t; |
---|
164 | 172 | |
---|
165 | | - |
---|
166 | 173 | typedef struct ftm_status_map_host_entry { |
---|
167 | 174 | wl_proxd_status_t proxd_status; |
---|
168 | 175 | rtt_reason_t rtt_reason; |
---|
169 | 176 | } ftm_status_map_host_entry_t; |
---|
170 | 177 | |
---|
| 178 | +static uint16 |
---|
| 179 | +rtt_result_ver(uint16 tlvid, const uint8 *p_data); |
---|
| 180 | + |
---|
171 | 181 | static int |
---|
172 | | -dhd_rtt_convert_results_to_host(rtt_report_t *rtt_report, uint8 *p_data, uint16 tlvid, uint16 len); |
---|
| 182 | +dhd_rtt_convert_results_to_host_v1(rtt_result_t *rtt_result, const uint8 *p_data, |
---|
| 183 | + uint16 tlvid, uint16 len); |
---|
| 184 | + |
---|
| 185 | +static int |
---|
| 186 | +dhd_rtt_convert_results_to_host_v2(rtt_result_t *rtt_result, const uint8 *p_data, |
---|
| 187 | + uint16 tlvid, uint16 len); |
---|
173 | 188 | |
---|
174 | 189 | static wifi_rate_t |
---|
175 | 190 | dhd_rtt_convert_rate_to_host(uint32 ratespec); |
---|
176 | 191 | |
---|
| 192 | +#if defined(WL_CFG80211) && defined(RTT_DEBUG) |
---|
| 193 | +const char * |
---|
| 194 | +ftm_cmdid_to_str(uint16 cmdid); |
---|
| 195 | +#endif /* WL_CFG80211 && RTT_DEBUG */ |
---|
| 196 | + |
---|
| 197 | +#ifdef WL_CFG80211 |
---|
177 | 198 | static int |
---|
178 | 199 | dhd_rtt_start(dhd_pub_t *dhd); |
---|
| 200 | +static int dhd_rtt_create_failure_result(rtt_status_info_t *rtt_status, |
---|
| 201 | + struct ether_addr *addr); |
---|
| 202 | +static void dhd_rtt_handle_rtt_session_end(dhd_pub_t *dhd); |
---|
| 203 | +static void dhd_rtt_timeout_work(struct work_struct *work); |
---|
| 204 | +#endif /* WL_CFG80211 */ |
---|
179 | 205 | static const int burst_duration_idx[] = {0, 0, 1, 2, 4, 8, 16, 32, 64, 128, 0, 0}; |
---|
180 | 206 | |
---|
181 | 207 | /* ftm status mapping to host status */ |
---|
182 | 208 | static const ftm_status_map_host_entry_t ftm_status_map_info[] = { |
---|
183 | | - {WL_PROXD_E_INCOMPLETE, RTT_REASON_FAILURE}, |
---|
184 | | - {WL_PROXD_E_OVERRIDDEN, RTT_REASON_FAILURE}, |
---|
185 | | - {WL_PROXD_E_ASAP_FAILED, RTT_REASON_FAILURE}, |
---|
186 | | - {WL_PROXD_E_NOTSTARTED, RTT_REASON_FAIL_NOT_SCHEDULED_YET}, |
---|
187 | | - {WL_PROXD_E_INVALIDAVB, RTT_REASON_FAIL_INVALID_TS}, |
---|
188 | | - {WL_PROXD_E_INCAPABLE, RTT_REASON_FAIL_NO_CAPABILITY}, |
---|
189 | | - {WL_PROXD_E_MISMATCH, RTT_REASON_FAILURE}, |
---|
190 | | - {WL_PROXD_E_DUP_SESSION, RTT_REASON_FAILURE}, |
---|
191 | | - {WL_PROXD_E_REMOTE_FAIL, RTT_REASON_FAILURE}, |
---|
192 | | - {WL_PROXD_E_REMOTE_INCAPABLE, RTT_REASON_FAILURE}, |
---|
193 | | - {WL_PROXD_E_SCHED_FAIL, RTT_REASON_FAIL_SCHEDULE}, |
---|
194 | | - {WL_PROXD_E_PROTO, RTT_REASON_FAIL_PROTOCOL}, |
---|
195 | | - {WL_PROXD_E_EXPIRED, RTT_REASON_FAILURE}, |
---|
196 | | - {WL_PROXD_E_TIMEOUT, RTT_REASON_FAIL_TM_TIMEOUT}, |
---|
197 | | - {WL_PROXD_E_NOACK, RTT_REASON_FAIL_NO_RSP}, |
---|
198 | | - {WL_PROXD_E_DEFERRED, RTT_REASON_FAILURE}, |
---|
199 | | - {WL_PROXD_E_INVALID_SID, RTT_REASON_FAILURE}, |
---|
200 | | - {WL_PROXD_E_REMOTE_CANCEL, RTT_REASON_FAILURE}, |
---|
201 | | - {WL_PROXD_E_CANCELED, RTT_REASON_ABORTED}, |
---|
202 | | - {WL_PROXD_E_INVALID_SESSION, RTT_REASON_FAILURE}, |
---|
203 | | - {WL_PROXD_E_BAD_STATE, RTT_REASON_FAILURE}, |
---|
204 | | - {WL_PROXD_E_ERROR, RTT_REASON_FAILURE}, |
---|
205 | | - {WL_PROXD_E_OK, RTT_REASON_SUCCESS} |
---|
206 | | -}; |
---|
207 | | - |
---|
208 | | -/* ftm tlv-id mapping */ |
---|
209 | | -static const ftm_strmap_entry_t ftm_tlvid_loginfo[] = { |
---|
210 | | - /* { WL_PROXD_TLV_ID_xxx, "text for WL_PROXD_TLV_ID_xxx" }, */ |
---|
211 | | - { WL_PROXD_TLV_ID_NONE, "none" }, |
---|
212 | | - { WL_PROXD_TLV_ID_METHOD, "method" }, |
---|
213 | | - { WL_PROXD_TLV_ID_FLAGS, "flags" }, |
---|
214 | | - { WL_PROXD_TLV_ID_CHANSPEC, "chanspec" }, |
---|
215 | | - { WL_PROXD_TLV_ID_TX_POWER, "tx power" }, |
---|
216 | | - { WL_PROXD_TLV_ID_RATESPEC, "ratespec" }, |
---|
217 | | - { WL_PROXD_TLV_ID_BURST_DURATION, "burst duration" }, |
---|
218 | | - { WL_PROXD_TLV_ID_BURST_PERIOD, "burst period" }, |
---|
219 | | - { WL_PROXD_TLV_ID_BURST_FTM_SEP, "burst ftm sep" }, |
---|
220 | | - { WL_PROXD_TLV_ID_BURST_NUM_FTM, "burst num ftm" }, |
---|
221 | | - { WL_PROXD_TLV_ID_NUM_BURST, "num burst" }, |
---|
222 | | - { WL_PROXD_TLV_ID_FTM_RETRIES, "ftm retries" }, |
---|
223 | | - { WL_PROXD_TLV_ID_BSS_INDEX, "BSS index" }, |
---|
224 | | - { WL_PROXD_TLV_ID_BSSID, "bssid" }, |
---|
225 | | - { WL_PROXD_TLV_ID_INIT_DELAY, "burst init delay" }, |
---|
226 | | - { WL_PROXD_TLV_ID_BURST_TIMEOUT, "burst timeout" }, |
---|
227 | | - { WL_PROXD_TLV_ID_EVENT_MASK, "event mask" }, |
---|
228 | | - { WL_PROXD_TLV_ID_FLAGS_MASK, "flags mask" }, |
---|
229 | | - { WL_PROXD_TLV_ID_PEER_MAC, "peer addr" }, |
---|
230 | | - { WL_PROXD_TLV_ID_FTM_REQ, "ftm req" }, |
---|
231 | | - { WL_PROXD_TLV_ID_LCI_REQ, "lci req" }, |
---|
232 | | - { WL_PROXD_TLV_ID_LCI, "lci" }, |
---|
233 | | - { WL_PROXD_TLV_ID_CIVIC_REQ, "civic req" }, |
---|
234 | | - { WL_PROXD_TLV_ID_CIVIC, "civic" }, |
---|
235 | | - { WL_PROXD_TLV_ID_AVAIL, "availability" }, |
---|
236 | | - { WL_PROXD_TLV_ID_SESSION_FLAGS, "session flags" }, |
---|
237 | | - { WL_PROXD_TLV_ID_SESSION_FLAGS_MASK, "session flags mask" }, |
---|
238 | | - { WL_PROXD_TLV_ID_RX_MAX_BURST, "rx max bursts" }, |
---|
239 | | - { WL_PROXD_TLV_ID_RANGING_INFO, "ranging info" }, |
---|
240 | | - { WL_PROXD_TLV_ID_RANGING_FLAGS, "ranging flags" }, |
---|
241 | | - { WL_PROXD_TLV_ID_RANGING_FLAGS_MASK, "ranging flags mask" }, |
---|
242 | | - /* output - 512 + x */ |
---|
243 | | - { WL_PROXD_TLV_ID_STATUS, "status" }, |
---|
244 | | - { WL_PROXD_TLV_ID_COUNTERS, "counters" }, |
---|
245 | | - { WL_PROXD_TLV_ID_INFO, "info" }, |
---|
246 | | - { WL_PROXD_TLV_ID_RTT_RESULT, "rtt result" }, |
---|
247 | | - { WL_PROXD_TLV_ID_AOA_RESULT, "aoa result" }, |
---|
248 | | - { WL_PROXD_TLV_ID_SESSION_INFO, "session info" }, |
---|
249 | | - { WL_PROXD_TLV_ID_SESSION_STATUS, "session status" }, |
---|
250 | | - { WL_PROXD_TLV_ID_SESSION_ID_LIST, "session ids" }, |
---|
251 | | - /* debug tlvs can be added starting 1024 */ |
---|
252 | | - { WL_PROXD_TLV_ID_DEBUG_MASK, "debug mask" }, |
---|
253 | | - { WL_PROXD_TLV_ID_COLLECT, "collect" }, |
---|
254 | | - { WL_PROXD_TLV_ID_STRBUF, "result" } |
---|
| 209 | + {WL_PROXD_E_INCOMPLETE, RTT_STATUS_FAILURE}, |
---|
| 210 | + {WL_PROXD_E_OVERRIDDEN, RTT_STATUS_FAILURE}, |
---|
| 211 | + {WL_PROXD_E_ASAP_FAILED, RTT_STATUS_FAILURE}, |
---|
| 212 | + {WL_PROXD_E_NOTSTARTED, RTT_STATUS_FAIL_NOT_SCHEDULED_YET}, |
---|
| 213 | + {WL_PROXD_E_INVALIDMEAS, RTT_STATUS_FAIL_INVALID_TS}, |
---|
| 214 | + {WL_PROXD_E_INCAPABLE, RTT_STATUS_FAIL_NO_CAPABILITY}, |
---|
| 215 | + {WL_PROXD_E_MISMATCH, RTT_STATUS_FAILURE}, |
---|
| 216 | + {WL_PROXD_E_DUP_SESSION, RTT_STATUS_FAILURE}, |
---|
| 217 | + {WL_PROXD_E_REMOTE_FAIL, RTT_STATUS_FAILURE}, |
---|
| 218 | + {WL_PROXD_E_REMOTE_INCAPABLE, RTT_STATUS_FAILURE}, |
---|
| 219 | + {WL_PROXD_E_SCHED_FAIL, RTT_STATUS_FAIL_SCHEDULE}, |
---|
| 220 | + {WL_PROXD_E_PROTO, RTT_STATUS_FAIL_PROTOCOL}, |
---|
| 221 | + {WL_PROXD_E_EXPIRED, RTT_STATUS_FAILURE}, |
---|
| 222 | + {WL_PROXD_E_TIMEOUT, RTT_STATUS_FAIL_TM_TIMEOUT}, |
---|
| 223 | + {WL_PROXD_E_NOACK, RTT_STATUS_FAIL_NO_RSP}, |
---|
| 224 | + {WL_PROXD_E_DEFERRED, RTT_STATUS_FAILURE}, |
---|
| 225 | + {WL_PROXD_E_INVALID_SID, RTT_STATUS_FAILURE}, |
---|
| 226 | + {WL_PROXD_E_REMOTE_CANCEL, RTT_STATUS_FAILURE}, |
---|
| 227 | + {WL_PROXD_E_CANCELED, RTT_STATUS_ABORTED}, |
---|
| 228 | + {WL_PROXD_E_INVALID_SESSION, RTT_STATUS_FAILURE}, |
---|
| 229 | + {WL_PROXD_E_BAD_STATE, RTT_STATUS_FAILURE}, |
---|
| 230 | + {WL_PROXD_E_ERROR, RTT_STATUS_FAILURE}, |
---|
| 231 | + {WL_PROXD_E_OK, RTT_STATUS_SUCCESS} |
---|
255 | 232 | }; |
---|
256 | 233 | |
---|
257 | 234 | static const ftm_strmap_entry_t ftm_event_type_loginfo[] = { |
---|
258 | | - /* wl_proxd_event_type_t, text-string */ |
---|
259 | | - { WL_PROXD_EVENT_NONE, "none" }, |
---|
| 235 | + /* wl_proxd_event_type_t, text-string */ |
---|
| 236 | + { WL_PROXD_EVENT_NONE, "none" }, |
---|
260 | 237 | { WL_PROXD_EVENT_SESSION_CREATE, "session create" }, |
---|
261 | 238 | { WL_PROXD_EVENT_SESSION_START, "session start" }, |
---|
262 | | - { WL_PROXD_EVENT_FTM_REQ, "FTM req" }, |
---|
| 239 | + { WL_PROXD_EVENT_FTM_REQ, "FTM req" }, |
---|
263 | 240 | { WL_PROXD_EVENT_BURST_START, "burst start" }, |
---|
264 | | - { WL_PROXD_EVENT_BURST_END, "burst end" }, |
---|
| 241 | + { WL_PROXD_EVENT_BURST_END, "burst end" }, |
---|
265 | 242 | { WL_PROXD_EVENT_SESSION_END, "session end" }, |
---|
266 | 243 | { WL_PROXD_EVENT_SESSION_RESTART, "session restart" }, |
---|
267 | 244 | { WL_PROXD_EVENT_BURST_RESCHED, "burst rescheduled" }, |
---|
268 | 245 | { WL_PROXD_EVENT_SESSION_DESTROY, "session destroy" }, |
---|
269 | | - { WL_PROXD_EVENT_RANGE_REQ, "range request" }, |
---|
270 | | - { WL_PROXD_EVENT_FTM_FRAME, "FTM frame" }, |
---|
271 | | - { WL_PROXD_EVENT_DELAY, "delay" }, |
---|
| 246 | + { WL_PROXD_EVENT_RANGE_REQ, "range request" }, |
---|
| 247 | + { WL_PROXD_EVENT_FTM_FRAME, "FTM frame" }, |
---|
| 248 | + { WL_PROXD_EVENT_DELAY, "delay" }, |
---|
272 | 249 | { WL_PROXD_EVENT_VS_INITIATOR_RPT, "initiator-report " }, /* rx initiator-rpt */ |
---|
273 | | - { WL_PROXD_EVENT_RANGING, "ranging " }, |
---|
| 250 | + { WL_PROXD_EVENT_RANGING, "ranging " }, |
---|
| 251 | + { WL_PROXD_EVENT_COLLECT, "collect" }, |
---|
| 252 | + { WL_PROXD_EVENT_MF_STATS, "mf_stats" }, |
---|
274 | 253 | }; |
---|
275 | 254 | |
---|
276 | 255 | /* |
---|
277 | 256 | * session-state --> text string mapping |
---|
278 | 257 | */ |
---|
279 | 258 | static const ftm_strmap_entry_t ftm_session_state_value_loginfo[] = { |
---|
280 | | - /* wl_proxd_session_state_t, text string */ |
---|
281 | | - { WL_PROXD_SESSION_STATE_CREATED, "created" }, |
---|
| 259 | + /* wl_proxd_session_state_t, text string */ |
---|
| 260 | + { WL_PROXD_SESSION_STATE_CREATED, "created" }, |
---|
282 | 261 | { WL_PROXD_SESSION_STATE_CONFIGURED, "configured" }, |
---|
283 | | - { WL_PROXD_SESSION_STATE_STARTED, "started" }, |
---|
284 | | - { WL_PROXD_SESSION_STATE_DELAY, "delay" }, |
---|
285 | | - { WL_PROXD_SESSION_STATE_USER_WAIT, "user-wait" }, |
---|
| 262 | + { WL_PROXD_SESSION_STATE_STARTED, "started" }, |
---|
| 263 | + { WL_PROXD_SESSION_STATE_DELAY, "delay" }, |
---|
| 264 | + { WL_PROXD_SESSION_STATE_USER_WAIT, "user-wait" }, |
---|
286 | 265 | { WL_PROXD_SESSION_STATE_SCHED_WAIT, "sched-wait" }, |
---|
287 | | - { WL_PROXD_SESSION_STATE_BURST, "burst" }, |
---|
288 | | - { WL_PROXD_SESSION_STATE_STOPPING, "stopping" }, |
---|
289 | | - { WL_PROXD_SESSION_STATE_ENDED, "ended" }, |
---|
| 266 | + { WL_PROXD_SESSION_STATE_BURST, "burst" }, |
---|
| 267 | + { WL_PROXD_SESSION_STATE_STOPPING, "stopping" }, |
---|
| 268 | + { WL_PROXD_SESSION_STATE_ENDED, "ended" }, |
---|
290 | 269 | { WL_PROXD_SESSION_STATE_DESTROYING, "destroying" }, |
---|
291 | | - { WL_PROXD_SESSION_STATE_NONE, "none" } |
---|
292 | | -}; |
---|
293 | | - |
---|
294 | | -/* |
---|
295 | | -* ranging-state --> text string mapping |
---|
296 | | -*/ |
---|
297 | | -static const ftm_strmap_entry_t ftm_ranging_state_value_loginfo [] = { |
---|
298 | | - /* wl_proxd_ranging_state_t, text string */ |
---|
299 | | - { WL_PROXD_RANGING_STATE_NONE, "none" }, |
---|
300 | | - { WL_PROXD_RANGING_STATE_NOTSTARTED, "nonstarted" }, |
---|
301 | | - { WL_PROXD_RANGING_STATE_INPROGRESS, "inprogress" }, |
---|
302 | | - { WL_PROXD_RANGING_STATE_DONE, "done" }, |
---|
| 270 | + { WL_PROXD_SESSION_STATE_NONE, "none" } |
---|
303 | 271 | }; |
---|
304 | 272 | |
---|
305 | 273 | /* |
---|
.. | .. |
---|
310 | 278 | { WL_PROXD_E_OVERRIDDEN, "overridden" }, |
---|
311 | 279 | { WL_PROXD_E_ASAP_FAILED, "ASAP failed" }, |
---|
312 | 280 | { WL_PROXD_E_NOTSTARTED, "not started" }, |
---|
313 | | - { WL_PROXD_E_INVALIDAVB, "invalid AVB" }, |
---|
314 | | - { WL_PROXD_E_INCAPABLE, "incapable" }, |
---|
315 | | - { WL_PROXD_E_MISMATCH, "mismatch"}, |
---|
| 281 | + { WL_PROXD_E_INVALIDMEAS, "invalid measurement" }, |
---|
| 282 | + { WL_PROXD_E_INCAPABLE, "incapable" }, |
---|
| 283 | + { WL_PROXD_E_MISMATCH, "mismatch"}, |
---|
316 | 284 | { WL_PROXD_E_DUP_SESSION, "dup session" }, |
---|
317 | 285 | { WL_PROXD_E_REMOTE_FAIL, "remote fail" }, |
---|
318 | | - { WL_PROXD_E_REMOTE_INCAPABLE, "remote incapable" }, |
---|
| 286 | + { WL_PROXD_E_REMOTE_INCAPABLE, "remote incapable" }, |
---|
319 | 287 | { WL_PROXD_E_SCHED_FAIL, "sched failure" }, |
---|
320 | 288 | { WL_PROXD_E_PROTO, "protocol error" }, |
---|
321 | 289 | { WL_PROXD_E_EXPIRED, "expired" }, |
---|
322 | 290 | { WL_PROXD_E_TIMEOUT, "timeout" }, |
---|
323 | 291 | { WL_PROXD_E_NOACK, "no ack" }, |
---|
324 | | - { WL_PROXD_E_DEFERRED, "deferred" }, |
---|
| 292 | + { WL_PROXD_E_DEFERRED, "deferred" }, |
---|
325 | 293 | { WL_PROXD_E_INVALID_SID, "invalid session id" }, |
---|
326 | 294 | { WL_PROXD_E_REMOTE_CANCEL, "remote cancel" }, |
---|
327 | | - { WL_PROXD_E_CANCELED, "canceled" }, |
---|
328 | | - { WL_PROXD_E_INVALID_SESSION, "invalid session" }, |
---|
329 | | - { WL_PROXD_E_BAD_STATE, "bad state" }, |
---|
| 295 | + { WL_PROXD_E_CANCELED, "canceled" }, |
---|
| 296 | + { WL_PROXD_E_INVALID_SESSION, "invalid session" }, |
---|
| 297 | + { WL_PROXD_E_BAD_STATE, "bad state" }, |
---|
330 | 298 | { WL_PROXD_E_ERROR, "error" }, |
---|
331 | | - { WL_PROXD_E_OK, "OK" } |
---|
| 299 | + { WL_PROXD_E_OK, "OK" } |
---|
332 | 300 | }; |
---|
333 | 301 | |
---|
334 | 302 | /* |
---|
335 | 303 | * time interval unit --> text string mapping |
---|
336 | 304 | */ |
---|
337 | 305 | static const ftm_strmap_entry_t ftm_tmu_value_loginfo[] = { |
---|
338 | | - /* wl_proxd_tmu_t, text-string */ |
---|
339 | | - { WL_PROXD_TMU_TU, "TU" }, |
---|
340 | | - { WL_PROXD_TMU_SEC, "sec" }, |
---|
| 306 | + /* wl_proxd_tmu_t, text-string */ |
---|
| 307 | + { WL_PROXD_TMU_TU, "TU" }, |
---|
| 308 | + { WL_PROXD_TMU_SEC, "sec" }, |
---|
341 | 309 | { WL_PROXD_TMU_MILLI_SEC, "ms" }, |
---|
342 | 310 | { WL_PROXD_TMU_MICRO_SEC, "us" }, |
---|
343 | 311 | { WL_PROXD_TMU_NANO_SEC, "ns" }, |
---|
344 | 312 | { WL_PROXD_TMU_PICO_SEC, "ps" } |
---|
345 | 313 | }; |
---|
346 | | - |
---|
347 | | -#define RSPEC_BW(rspec) ((rspec) & WL_RSPEC_BW_MASK) |
---|
348 | | -#define RSPEC_IS20MHZ(rspec) (RSPEC_BW(rspec) == WL_RSPEC_BW_20MHZ) |
---|
349 | | -#define RSPEC_IS40MHZ(rspec) (RSPEC_BW(rspec) == WL_RSPEC_BW_40MHZ) |
---|
350 | | -#define RSPEC_IS80MHZ(rspec) (RSPEC_BW(rspec) == WL_RSPEC_BW_80MHZ) |
---|
351 | | -#define RSPEC_IS160MHZ(rspec) (RSPEC_BW(rspec) == WL_RSPEC_BW_160MHZ) |
---|
352 | | - |
---|
353 | | -#define IS_MCS(rspec) (((rspec) & WL_RSPEC_ENCODING_MASK) != WL_RSPEC_ENCODE_RATE) |
---|
354 | | -#define IS_STBC(rspec) (((((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_HT) || \ |
---|
355 | | - (((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_VHT)) && \ |
---|
356 | | - (((rspec) & WL_RSPEC_STBC) == WL_RSPEC_STBC)) |
---|
357 | | -#define RSPEC_ISSGI(rspec) (((rspec) & WL_RSPEC_SGI) != 0) |
---|
358 | | -#define RSPEC_ISLDPC(rspec) (((rspec) & WL_RSPEC_LDPC) != 0) |
---|
359 | | -#define RSPEC_ISSTBC(rspec) (((rspec) & WL_RSPEC_STBC) != 0) |
---|
360 | | -#define RSPEC_ISTXBF(rspec) (((rspec) & WL_RSPEC_TXBF) != 0) |
---|
361 | | -#define RSPEC_ISVHT(rspec) (((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_VHT) |
---|
362 | | -#define RSPEC_ISHT(rspec) (((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_HT) |
---|
363 | | -#define RSPEC_ISLEGACY(rspec) (((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_RATE) |
---|
364 | | -#define RSPEC2RATE(rspec) (RSPEC_ISLEGACY(rspec) ? \ |
---|
365 | | - ((rspec) & RSPEC_RATE_MASK) : rate_rspec2rate(rspec)) |
---|
366 | | -/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */ |
---|
367 | | -#define RSPEC2KBPS(rspec) rate_rspec2rate(rspec) |
---|
368 | 314 | |
---|
369 | 315 | struct ieee_80211_mcs_rate_info { |
---|
370 | 316 | uint8 constellation_bits; |
---|
.. | .. |
---|
449 | 395 | } /* wlc_rate_mcs2rate */ |
---|
450 | 396 | |
---|
451 | 397 | /** take a well formed ratespec_t arg and return phy rate in [Kbps] units */ |
---|
452 | | -int |
---|
| 398 | +static uint32 |
---|
453 | 399 | rate_rspec2rate(uint32 rspec) |
---|
454 | 400 | { |
---|
455 | | - int rate = -1; |
---|
| 401 | + int rate = 0; |
---|
456 | 402 | |
---|
457 | 403 | if (RSPEC_ISLEGACY(rspec)) { |
---|
458 | 404 | rate = 500 * (rspec & WL_RSPEC_RATE_MASK); |
---|
.. | .. |
---|
469 | 415 | } else if (RSPEC_ISVHT(rspec)) { |
---|
470 | 416 | uint mcs = (rspec & WL_RSPEC_VHT_MCS_MASK); |
---|
471 | 417 | uint nss = (rspec & WL_RSPEC_VHT_NSS_MASK) >> WL_RSPEC_VHT_NSS_SHIFT; |
---|
472 | | - |
---|
473 | | - ASSERT(mcs <= 9); |
---|
474 | | - ASSERT(nss <= 8); |
---|
| 418 | + if (mcs > 9 || nss > 8) { |
---|
| 419 | + DHD_RTT(("%s: Invalid mcs %d or nss %d\n", __FUNCTION__, mcs, nss)); |
---|
| 420 | + goto exit; |
---|
| 421 | + } |
---|
475 | 422 | |
---|
476 | 423 | rate = rate_mcs2rate(mcs, nss, RSPEC_BW(rspec), RSPEC_ISSGI(rspec)); |
---|
477 | 424 | } else { |
---|
478 | | - ASSERT(0); |
---|
| 425 | + DHD_RTT(("%s: wrong rspec:%d\n", __FUNCTION__, rspec)); |
---|
479 | 426 | } |
---|
480 | | - |
---|
481 | | - return (rate == 0) ? -1 : rate; |
---|
| 427 | +exit: |
---|
| 428 | + return rate; |
---|
482 | 429 | } |
---|
483 | 430 | |
---|
484 | 431 | char resp_buf[WLC_IOCTL_SMLEN]; |
---|
.. | .. |
---|
536 | 483 | } |
---|
537 | 484 | p_entry++; /* next entry */ |
---|
538 | 485 | } |
---|
539 | | - return RTT_REASON_FAILURE; /* not found */ |
---|
| 486 | + return RTT_STATUS_FAILURE; /* not found */ |
---|
540 | 487 | } |
---|
541 | 488 | /* |
---|
542 | 489 | * lookup 'id' (as a key) from a table |
---|
.. | .. |
---|
578 | 525 | return "invalid"; |
---|
579 | 526 | } |
---|
580 | 527 | |
---|
581 | | - |
---|
582 | | -#ifdef RTT_DEBUG |
---|
583 | | - |
---|
| 528 | +#if defined(WL_CFG80211) && defined(RTT_DEBUG) |
---|
584 | 529 | /* define entry, e.g. { WL_PROXD_CMD_xxx, "WL_PROXD_CMD_xxx" } */ |
---|
585 | 530 | #define DEF_STRMAP_ENTRY(id) { (id), #id } |
---|
586 | 531 | |
---|
.. | .. |
---|
613 | 558 | /* |
---|
614 | 559 | * map a ftm cmd-id to a text-string for display |
---|
615 | 560 | */ |
---|
616 | | -static const char * |
---|
| 561 | +const char * |
---|
617 | 562 | ftm_cmdid_to_str(uint16 cmdid) |
---|
618 | 563 | { |
---|
619 | 564 | return ftm_map_id_to_str((int32) cmdid, &ftm_cmdid_map[0], ARRAYSIZE(ftm_cmdid_map)); |
---|
620 | 565 | } |
---|
621 | | -#endif /* RTT_DEBUG */ |
---|
622 | | - |
---|
| 566 | +#endif /* WL_CFG80211 && RTT_DEBUG */ |
---|
623 | 567 | |
---|
624 | 568 | /* |
---|
625 | 569 | * convert BCME_xxx error codes into related error strings |
---|
.. | .. |
---|
674 | 618 | ARRAYSIZE(ftm_session_state_value_loginfo)); |
---|
675 | 619 | } |
---|
676 | 620 | |
---|
677 | | - |
---|
| 621 | +#ifdef WL_CFG80211 |
---|
678 | 622 | /* |
---|
679 | 623 | * send 'proxd' iovar for all ftm get-related commands |
---|
680 | 624 | */ |
---|
.. | .. |
---|
690 | 634 | status = dhd_getiovar(dhd, 0, "proxd", (char *)p_proxd_iov, |
---|
691 | 635 | proxd_iovsize, (char **)&p_iovresp, WLC_IOCTL_SMLEN); |
---|
692 | 636 | if (status != BCME_OK) { |
---|
693 | | - DHD_ERROR(("%s: failed to send getbuf proxd iovar (CMD ID : %d), status=%d\n", |
---|
| 637 | + DHD_RTT_ERR(("%s: failed to send getbuf proxd iovar (CMD ID : %d), status=%d\n", |
---|
694 | 638 | __FUNCTION__, p_subcmd_info->cmdid, status)); |
---|
695 | 639 | return status; |
---|
696 | 640 | } |
---|
.. | .. |
---|
702 | 646 | |
---|
703 | 647 | tlvs_len = ltoh16(p_iovresp->len) - WL_PROXD_IOV_HDR_SIZE; |
---|
704 | 648 | if (tlvs_len < 0) { |
---|
705 | | - DHD_ERROR(("%s: alert, p_iovresp->len(%d) should not be smaller than %d\n", |
---|
| 649 | + DHD_RTT_ERR(("%s: alert, p_iovresp->len(%d) should not be smaller than %d\n", |
---|
706 | 650 | __FUNCTION__, ltoh16(p_iovresp->len), (int) WL_PROXD_IOV_HDR_SIZE)); |
---|
707 | 651 | tlvs_len = 0; |
---|
708 | 652 | } |
---|
.. | .. |
---|
716 | 660 | return status; |
---|
717 | 661 | } |
---|
718 | 662 | |
---|
719 | | - |
---|
720 | 663 | static wl_proxd_iov_t * |
---|
721 | 664 | rtt_alloc_getset_buf(wl_proxd_method_t method, wl_proxd_session_id_t session_id, |
---|
722 | 665 | wl_proxd_cmd_t cmdid, uint16 tlvs_bufsize, uint16 *p_out_bufsize) |
---|
723 | 666 | { |
---|
724 | 667 | uint16 proxd_iovsize; |
---|
725 | | - uint16 kflags; |
---|
| 668 | + uint32 kflags; |
---|
726 | 669 | wl_proxd_tlv_t *p_tlv; |
---|
727 | 670 | wl_proxd_iov_t *p_proxd_iov = (wl_proxd_iov_t *) NULL; |
---|
728 | 671 | |
---|
.. | .. |
---|
733 | 676 | |
---|
734 | 677 | p_proxd_iov = kzalloc(proxd_iovsize, kflags); |
---|
735 | 678 | if (p_proxd_iov == NULL) { |
---|
736 | | - DHD_ERROR(("error: failed to allocate %d bytes of memory\n", proxd_iovsize)); |
---|
| 679 | + DHD_RTT_ERR(("error: failed to allocate %d bytes of memory\n", proxd_iovsize)); |
---|
737 | 680 | return NULL; |
---|
738 | 681 | } |
---|
739 | 682 | |
---|
.. | .. |
---|
754 | 697 | return p_proxd_iov; |
---|
755 | 698 | } |
---|
756 | 699 | |
---|
757 | | - |
---|
758 | 700 | static int |
---|
759 | 701 | dhd_rtt_common_get_handler(dhd_pub_t *dhd, ftm_subcmd_info_t *p_subcmd_info, |
---|
760 | 702 | wl_proxd_method_t method, |
---|
.. | .. |
---|
767 | 709 | DHD_RTT(("enter %s: method=%d, session_id=%d, cmdid=%d(%s)\n", |
---|
768 | 710 | __FUNCTION__, method, session_id, p_subcmd_info->cmdid, |
---|
769 | 711 | ftm_cmdid_to_str(p_subcmd_info->cmdid))); |
---|
770 | | -#endif |
---|
| 712 | +#endif // endif |
---|
771 | 713 | /* alloc mem for ioctl headr + reserved 0 bufsize for tlvs (initialize to zero) */ |
---|
772 | 714 | p_proxd_iov = rtt_alloc_getset_buf(method, session_id, p_subcmd_info->cmdid, |
---|
773 | 715 | 0, &proxd_iovsize); |
---|
.. | .. |
---|
809 | 751 | int ret; |
---|
810 | 752 | |
---|
811 | 753 | #ifdef RTT_DEBUG |
---|
812 | | - DHD_ERROR(("enter %s: method=%d, session_id=%d, cmdid=%d(%s)\n", |
---|
| 754 | + DHD_RTT(("enter %s: method=%d, session_id=%d, cmdid=%d(%s)\n", |
---|
813 | 755 | __FUNCTION__, method, session_id, p_subcmd_info->cmdid, |
---|
814 | 756 | ftm_cmdid_to_str(p_subcmd_info->cmdid))); |
---|
815 | | -#endif |
---|
| 757 | +#endif // endif |
---|
| 758 | + |
---|
816 | 759 | /* allocate and initialize a temp buffer for 'set proxd' iovar */ |
---|
817 | 760 | proxd_iovsize = 0; |
---|
818 | 761 | p_proxd_iov = rtt_alloc_getset_buf(method, session_id, p_subcmd_info->cmdid, |
---|
.. | .. |
---|
824 | 767 | ret = dhd_iovar(dhd, 0, "proxd", (char *)p_proxd_iov, proxd_iovsize, NULL, 0, TRUE); |
---|
825 | 768 | #ifdef RTT_DEBUG |
---|
826 | 769 | if (ret != BCME_OK) { |
---|
827 | | - DHD_ERROR(("error: Proxd IOVAR failed, status=%d\n", ret)); |
---|
| 770 | + DHD_RTT(("error: IOVAR failed, status=%d\n", ret)); |
---|
828 | 771 | } |
---|
829 | | -#endif |
---|
| 772 | +#endif // endif |
---|
830 | 773 | /* clean up */ |
---|
831 | 774 | kfree(p_proxd_iov); |
---|
| 775 | + |
---|
| 776 | + return ret; |
---|
| 777 | +} |
---|
| 778 | +#endif /* WL_CFG80211 */ |
---|
| 779 | + |
---|
| 780 | +/* gets the length and returns the version |
---|
| 781 | + * of the wl_proxd_collect_event_t version |
---|
| 782 | + */ |
---|
| 783 | +static uint |
---|
| 784 | +rtt_collect_data_event_ver(uint16 len) |
---|
| 785 | +{ |
---|
| 786 | + if (len > sizeof(wl_proxd_collect_event_data_v3_t)) { |
---|
| 787 | + return WL_PROXD_COLLECT_EVENT_DATA_VERSION_MAX; |
---|
| 788 | + } else if (len == sizeof(wl_proxd_collect_event_data_v3_t)) { |
---|
| 789 | + return WL_PROXD_COLLECT_EVENT_DATA_VERSION_3; |
---|
| 790 | + } else if (len == sizeof(wl_proxd_collect_event_data_v2_t)) { |
---|
| 791 | + return WL_PROXD_COLLECT_EVENT_DATA_VERSION_2; |
---|
| 792 | + } else { |
---|
| 793 | + return WL_PROXD_COLLECT_EVENT_DATA_VERSION_1; |
---|
| 794 | + } |
---|
| 795 | +} |
---|
| 796 | + |
---|
| 797 | +static void |
---|
| 798 | +rtt_collect_event_data_display(uint8 ver, void *ctx, const uint8 *p_data, uint16 len) |
---|
| 799 | +{ |
---|
| 800 | + int i; |
---|
| 801 | + wl_proxd_collect_event_data_v1_t *p_collect_data_v1 = NULL; |
---|
| 802 | + wl_proxd_collect_event_data_v2_t *p_collect_data_v2 = NULL; |
---|
| 803 | + wl_proxd_collect_event_data_v3_t *p_collect_data_v3 = NULL; |
---|
| 804 | + |
---|
| 805 | + if (!ctx || !p_data) { |
---|
| 806 | + return; |
---|
| 807 | + } |
---|
| 808 | + |
---|
| 809 | + switch (ver) { |
---|
| 810 | + case WL_PROXD_COLLECT_EVENT_DATA_VERSION_1: |
---|
| 811 | + DHD_RTT(("\tVERSION_1\n")); |
---|
| 812 | + memcpy(ctx, p_data, sizeof(wl_proxd_collect_event_data_v1_t)); |
---|
| 813 | + p_collect_data_v1 = (wl_proxd_collect_event_data_v1_t *)ctx; |
---|
| 814 | + DHD_RTT(("\tH_RX\n")); |
---|
| 815 | + for (i = 0; i < K_TOF_COLLECT_H_SIZE_20MHZ; i++) { |
---|
| 816 | + p_collect_data_v1->H_RX[i] = ltoh32_ua(&p_collect_data_v1->H_RX[i]); |
---|
| 817 | + DHD_RTT(("\t%u\n", p_collect_data_v1->H_RX[i])); |
---|
| 818 | + } |
---|
| 819 | + DHD_RTT(("\n")); |
---|
| 820 | + DHD_RTT(("\tH_LB\n")); |
---|
| 821 | + for (i = 0; i < K_TOF_COLLECT_H_SIZE_20MHZ; i++) { |
---|
| 822 | + p_collect_data_v1->H_LB[i] = ltoh32_ua(&p_collect_data_v1->H_LB[i]); |
---|
| 823 | + DHD_RTT(("\t%u\n", p_collect_data_v1->H_LB[i])); |
---|
| 824 | + } |
---|
| 825 | + DHD_RTT(("\n")); |
---|
| 826 | + DHD_RTT(("\tri_rr\n")); |
---|
| 827 | + for (i = 0; i < FTM_TPK_RI_RR_LEN; i++) { |
---|
| 828 | + DHD_RTT(("\t%u\n", p_collect_data_v1->ri_rr[i])); |
---|
| 829 | + } |
---|
| 830 | + p_collect_data_v1->phy_err_mask = ltoh32_ua(&p_collect_data_v1->phy_err_mask); |
---|
| 831 | + DHD_RTT(("\tphy_err_mask=0x%x\n", p_collect_data_v1->phy_err_mask)); |
---|
| 832 | + break; |
---|
| 833 | + case WL_PROXD_COLLECT_EVENT_DATA_VERSION_2: |
---|
| 834 | + memcpy(ctx, p_data, sizeof(wl_proxd_collect_event_data_v2_t)); |
---|
| 835 | + p_collect_data_v2 = (wl_proxd_collect_event_data_v2_t *)ctx; |
---|
| 836 | + DHD_RTT(("\tH_RX\n")); |
---|
| 837 | + for (i = 0; i < K_TOF_COLLECT_H_SIZE_20MHZ; i++) { |
---|
| 838 | + p_collect_data_v2->H_RX[i] = ltoh32_ua(&p_collect_data_v2->H_RX[i]); |
---|
| 839 | + DHD_RTT(("\t%u\n", p_collect_data_v2->H_RX[i])); |
---|
| 840 | + } |
---|
| 841 | + DHD_RTT(("\n")); |
---|
| 842 | + DHD_RTT(("\tH_LB\n")); |
---|
| 843 | + for (i = 0; i < K_TOF_COLLECT_H_SIZE_20MHZ; i++) { |
---|
| 844 | + p_collect_data_v2->H_LB[i] = ltoh32_ua(&p_collect_data_v2->H_LB[i]); |
---|
| 845 | + DHD_RTT(("\t%u\n", p_collect_data_v2->H_LB[i])); |
---|
| 846 | + } |
---|
| 847 | + DHD_RTT(("\n")); |
---|
| 848 | + DHD_RTT(("\tri_rr\n")); |
---|
| 849 | + for (i = 0; i < FTM_TPK_RI_RR_LEN_SECURE_2_0; i++) { |
---|
| 850 | + DHD_RTT(("\t%u\n", p_collect_data_v2->ri_rr[i])); |
---|
| 851 | + } |
---|
| 852 | + p_collect_data_v2->phy_err_mask = ltoh32_ua(&p_collect_data_v2->phy_err_mask); |
---|
| 853 | + DHD_RTT(("\tphy_err_mask=0x%x\n", p_collect_data_v2->phy_err_mask)); |
---|
| 854 | + break; |
---|
| 855 | + case WL_PROXD_COLLECT_EVENT_DATA_VERSION_3: |
---|
| 856 | + memcpy(ctx, p_data, sizeof(wl_proxd_collect_event_data_v3_t)); |
---|
| 857 | + p_collect_data_v3 = (wl_proxd_collect_event_data_v3_t *)ctx; |
---|
| 858 | + switch (p_collect_data_v3->version) { |
---|
| 859 | + case WL_PROXD_COLLECT_EVENT_DATA_VERSION_3: |
---|
| 860 | + if (p_collect_data_v3->length != |
---|
| 861 | + (len - OFFSETOF(wl_proxd_collect_event_data_v3_t, H_LB))) { |
---|
| 862 | + DHD_RTT(("\tversion/length mismatch\n")); |
---|
| 863 | + break; |
---|
| 864 | + } |
---|
| 865 | + DHD_RTT(("\tH_RX\n")); |
---|
| 866 | + for (i = 0; i < K_TOF_COLLECT_H_SIZE_20MHZ; i++) { |
---|
| 867 | + p_collect_data_v3->H_RX[i] = |
---|
| 868 | + ltoh32_ua(&p_collect_data_v3->H_RX[i]); |
---|
| 869 | + DHD_RTT(("\t%u\n", p_collect_data_v3->H_RX[i])); |
---|
| 870 | + } |
---|
| 871 | + DHD_RTT(("\n")); |
---|
| 872 | + DHD_RTT(("\tH_LB\n")); |
---|
| 873 | + for (i = 0; i < K_TOF_COLLECT_H_SIZE_20MHZ; i++) { |
---|
| 874 | + p_collect_data_v3->H_LB[i] = |
---|
| 875 | + ltoh32_ua(&p_collect_data_v3->H_LB[i]); |
---|
| 876 | + DHD_RTT(("\t%u\n", p_collect_data_v3->H_LB[i])); |
---|
| 877 | + } |
---|
| 878 | + DHD_RTT(("\n")); |
---|
| 879 | + DHD_RTT(("\tri_rr\n")); |
---|
| 880 | + for (i = 0; i < FTM_TPK_RI_RR_LEN_SECURE_2_0; i++) { |
---|
| 881 | + DHD_RTT(("\t%u\n", p_collect_data_v3->ri_rr[i])); |
---|
| 882 | + } |
---|
| 883 | + p_collect_data_v3->phy_err_mask = |
---|
| 884 | + ltoh32_ua(&p_collect_data_v3->phy_err_mask); |
---|
| 885 | + DHD_RTT(("\tphy_err_mask=0x%x\n", p_collect_data_v3->phy_err_mask)); |
---|
| 886 | + break; |
---|
| 887 | + /* future case */ |
---|
| 888 | + } |
---|
| 889 | + break; |
---|
| 890 | + } |
---|
| 891 | +} |
---|
| 892 | + |
---|
| 893 | +static uint16 |
---|
| 894 | +rtt_result_ver(uint16 tlvid, const uint8 *p_data) |
---|
| 895 | +{ |
---|
| 896 | + uint16 ret = BCME_OK; |
---|
| 897 | + const wl_proxd_rtt_result_v2_t *r_v2 = NULL; |
---|
| 898 | + |
---|
| 899 | + switch (tlvid) { |
---|
| 900 | + case WL_PROXD_TLV_ID_RTT_RESULT: |
---|
| 901 | + BCM_REFERENCE(p_data); |
---|
| 902 | + ret = WL_PROXD_RTT_RESULT_VERSION_1; |
---|
| 903 | + break; |
---|
| 904 | + case WL_PROXD_TLV_ID_RTT_RESULT_V2: |
---|
| 905 | + if (p_data) { |
---|
| 906 | + r_v2 = (const wl_proxd_rtt_result_v2_t *)p_data; |
---|
| 907 | + if (r_v2->version == WL_PROXD_RTT_RESULT_VERSION_2) { |
---|
| 908 | + ret = WL_PROXD_RTT_RESULT_VERSION_2; |
---|
| 909 | + } |
---|
| 910 | + } |
---|
| 911 | + break; |
---|
| 912 | + default: |
---|
| 913 | + DHD_RTT_ERR(("%s: > Unsupported TLV ID %d\n", |
---|
| 914 | + __FUNCTION__, tlvid)); |
---|
| 915 | + break; |
---|
| 916 | + } |
---|
832 | 917 | return ret; |
---|
833 | 918 | } |
---|
834 | 919 | |
---|
| 920 | +/* pretty hex print a contiguous buffer */ |
---|
| 921 | +static void |
---|
| 922 | +rtt_prhex(const char *msg, const uint8 *buf, uint nbytes) |
---|
| 923 | +{ |
---|
| 924 | + char line[128], *p; |
---|
| 925 | + int len = sizeof(line); |
---|
| 926 | + int nchar; |
---|
| 927 | + uint i; |
---|
| 928 | + |
---|
| 929 | + if (msg && (msg[0] != '\0')) |
---|
| 930 | + DHD_RTT(("%s:\n", msg)); |
---|
| 931 | + |
---|
| 932 | + p = line; |
---|
| 933 | + for (i = 0; i < nbytes; i++) { |
---|
| 934 | + if (i % 16 == 0) { |
---|
| 935 | + nchar = snprintf(p, len, " %04d: ", i); /* line prefix */ |
---|
| 936 | + p += nchar; |
---|
| 937 | + len -= nchar; |
---|
| 938 | + } |
---|
| 939 | + if (len > 0) { |
---|
| 940 | + nchar = snprintf(p, len, "%02x ", buf[i]); |
---|
| 941 | + p += nchar; |
---|
| 942 | + len -= nchar; |
---|
| 943 | + } |
---|
| 944 | + |
---|
| 945 | + if (i % 16 == 15) { |
---|
| 946 | + DHD_RTT(("%s\n", line)); /* flush line */ |
---|
| 947 | + p = line; |
---|
| 948 | + len = sizeof(line); |
---|
| 949 | + } |
---|
| 950 | + } |
---|
| 951 | + |
---|
| 952 | + /* flush last partial line */ |
---|
| 953 | + if (p != line) |
---|
| 954 | + DHD_RTT(("%s\n", line)); |
---|
| 955 | +} |
---|
| 956 | + |
---|
835 | 957 | static int |
---|
836 | | -rtt_unpack_xtlv_cbfn(void *ctx, uint8 *p_data, uint16 tlvid, uint16 len) |
---|
| 958 | +rtt_unpack_xtlv_cbfn(void *ctx, const uint8 *p_data, uint16 tlvid, uint16 len) |
---|
837 | 959 | { |
---|
838 | 960 | int ret = BCME_OK; |
---|
839 | | - wl_proxd_ftm_session_status_t *p_data_info; |
---|
| 961 | + int i; |
---|
| 962 | + wl_proxd_ftm_session_status_t *p_data_info = NULL; |
---|
| 963 | + uint32 chan_data_entry = 0; |
---|
| 964 | + uint16 expected_rtt_result_ver = 0; |
---|
| 965 | + |
---|
| 966 | + BCM_REFERENCE(p_data_info); |
---|
| 967 | + |
---|
840 | 968 | switch (tlvid) { |
---|
841 | 969 | case WL_PROXD_TLV_ID_RTT_RESULT: |
---|
842 | | - ret = dhd_rtt_convert_results_to_host((rtt_report_t *)ctx, |
---|
843 | | - p_data, tlvid, len); |
---|
| 970 | + case WL_PROXD_TLV_ID_RTT_RESULT_V2: |
---|
| 971 | + DHD_RTT(("WL_PROXD_TLV_ID_RTT_RESULT\n")); |
---|
| 972 | + expected_rtt_result_ver = rtt_result_ver(tlvid, p_data); |
---|
| 973 | + switch (expected_rtt_result_ver) { |
---|
| 974 | + case WL_PROXD_RTT_RESULT_VERSION_1: |
---|
| 975 | + ret = dhd_rtt_convert_results_to_host_v1((rtt_result_t *)ctx, |
---|
| 976 | + p_data, tlvid, len); |
---|
| 977 | + break; |
---|
| 978 | + case WL_PROXD_RTT_RESULT_VERSION_2: |
---|
| 979 | + ret = dhd_rtt_convert_results_to_host_v2((rtt_result_t *)ctx, |
---|
| 980 | + p_data, tlvid, len); |
---|
| 981 | + break; |
---|
| 982 | + default: |
---|
| 983 | + DHD_RTT_ERR((" > Unsupported RTT_RESULT version\n")); |
---|
| 984 | + ret = BCME_UNSUPPORTED; |
---|
| 985 | + break; |
---|
| 986 | + } |
---|
844 | 987 | break; |
---|
845 | 988 | case WL_PROXD_TLV_ID_SESSION_STATUS: |
---|
| 989 | + DHD_RTT(("WL_PROXD_TLV_ID_SESSION_STATUS\n")); |
---|
846 | 990 | memcpy(ctx, p_data, sizeof(wl_proxd_ftm_session_status_t)); |
---|
847 | 991 | p_data_info = (wl_proxd_ftm_session_status_t *)ctx; |
---|
| 992 | + p_data_info->sid = ltoh16_ua(&p_data_info->sid); |
---|
848 | 993 | p_data_info->state = ltoh16_ua(&p_data_info->state); |
---|
849 | 994 | p_data_info->status = ltoh32_ua(&p_data_info->status); |
---|
| 995 | + p_data_info->burst_num = ltoh16_ua(&p_data_info->burst_num); |
---|
| 996 | + DHD_RTT(("\tsid=%u, state=%d, status=%d, burst_num=%u\n", |
---|
| 997 | + p_data_info->sid, p_data_info->state, |
---|
| 998 | + p_data_info->status, p_data_info->burst_num)); |
---|
| 999 | + |
---|
| 1000 | + break; |
---|
| 1001 | + case WL_PROXD_TLV_ID_COLLECT_DATA: |
---|
| 1002 | + DHD_RTT(("WL_PROXD_TLV_ID_COLLECT_DATA\n")); |
---|
| 1003 | + rtt_collect_event_data_display( |
---|
| 1004 | + rtt_collect_data_event_ver(len), |
---|
| 1005 | + ctx, p_data, len); |
---|
| 1006 | + break; |
---|
| 1007 | + case WL_PROXD_TLV_ID_COLLECT_CHAN_DATA: |
---|
| 1008 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
| 1009 | + DHD_RTT(("WL_PROXD_TLV_ID_COLLECT_CHAN_DATA\n")); |
---|
| 1010 | + DHD_RTT(("\tchan est %u\n", (uint32) (len / sizeof(uint32)))); |
---|
| 1011 | + for (i = 0; i < (len/sizeof(chan_data_entry)); i++) { |
---|
| 1012 | + uint32 *p = (uint32*)p_data; |
---|
| 1013 | + chan_data_entry = ltoh32_ua(p + i); |
---|
| 1014 | + DHD_RTT(("\t%u\n", chan_data_entry)); |
---|
| 1015 | + } |
---|
| 1016 | + GCC_DIAGNOSTIC_POP(); |
---|
| 1017 | + break; |
---|
| 1018 | + case WL_PROXD_TLV_ID_MF_STATS_DATA: |
---|
| 1019 | + DHD_RTT(("WL_PROXD_TLV_ID_MF_STATS_DATA\n")); |
---|
| 1020 | + DHD_RTT(("\tmf stats len=%u\n", len)); |
---|
| 1021 | + rtt_prhex("", p_data, len); |
---|
850 | 1022 | break; |
---|
851 | 1023 | default: |
---|
852 | | - DHD_ERROR(("> Unsupported TLV ID %d\n", tlvid)); |
---|
| 1024 | + DHD_RTT_ERR(("> Unsupported TLV ID %d\n", tlvid)); |
---|
853 | 1025 | ret = BCME_ERROR; |
---|
854 | 1026 | break; |
---|
855 | 1027 | } |
---|
856 | 1028 | |
---|
857 | 1029 | return ret; |
---|
858 | 1030 | } |
---|
| 1031 | + |
---|
| 1032 | +#ifdef WL_CFG80211 |
---|
859 | 1033 | static int |
---|
860 | 1034 | rtt_handle_config_options(wl_proxd_session_id_t session_id, wl_proxd_tlv_t **p_tlv, |
---|
861 | 1035 | uint16 *p_buf_space_left, ftm_config_options_info_t *ftm_configs, int ftm_cfg_cnt) |
---|
.. | .. |
---|
885 | 1059 | flags_mask = htol32(flags_mask); |
---|
886 | 1060 | /* setup flags_mask TLV */ |
---|
887 | 1061 | ret = bcm_pack_xtlv_entry((uint8 **)p_tlv, p_buf_space_left, |
---|
888 | | - type, sizeof(uint32), &flags_mask, BCM_XTLV_OPTION_ALIGN32); |
---|
| 1062 | + type, sizeof(uint32), (uint8 *)&flags_mask, BCM_XTLV_OPTION_ALIGN32); |
---|
889 | 1063 | if (ret != BCME_OK) { |
---|
890 | | - DHD_ERROR(("%s : bcm_pack_xltv_entry() for mask flags failed, status=%d\n", |
---|
| 1064 | + DHD_RTT_ERR(("%s : bcm_pack_xltv_entry() for mask flags failed, status=%d\n", |
---|
891 | 1065 | __FUNCTION__, ret)); |
---|
892 | 1066 | goto exit; |
---|
893 | 1067 | } |
---|
.. | .. |
---|
896 | 1070 | WL_PROXD_TLV_ID_FLAGS : WL_PROXD_TLV_ID_SESSION_FLAGS; |
---|
897 | 1071 | /* setup flags TLV */ |
---|
898 | 1072 | ret = bcm_pack_xtlv_entry((uint8 **)p_tlv, p_buf_space_left, |
---|
899 | | - type, sizeof(uint32), &flags, BCM_XTLV_OPTION_ALIGN32); |
---|
| 1073 | + type, sizeof(uint32), (uint8 *)&flags, BCM_XTLV_OPTION_ALIGN32); |
---|
900 | 1074 | if (ret != BCME_OK) { |
---|
901 | | -//#ifdef RTT_DEBUG |
---|
| 1075 | +#ifdef RTT_DEBUG |
---|
902 | 1076 | DHD_RTT(("%s: bcm_pack_xltv_entry() for flags failed, status=%d\n", |
---|
903 | 1077 | __FUNCTION__, ret)); |
---|
904 | | -//#endif |
---|
| 1078 | +#endif // endif |
---|
905 | 1079 | } |
---|
906 | 1080 | exit: |
---|
907 | 1081 | return ret; |
---|
.. | .. |
---|
947 | 1121 | break; |
---|
948 | 1122 | case WL_PROXD_TLV_ID_BSSID: /* mac address */ |
---|
949 | 1123 | case WL_PROXD_TLV_ID_PEER_MAC: |
---|
| 1124 | + case WL_PROXD_TLV_ID_CUR_ETHER_ADDR: |
---|
950 | 1125 | p_src_data = &p_config_param_info->mac_addr; |
---|
951 | 1126 | src_data_size = sizeof(struct ether_addr); |
---|
952 | 1127 | break; |
---|
.. | .. |
---|
963 | 1138 | break; |
---|
964 | 1139 | } |
---|
965 | 1140 | if (ret != BCME_OK) { |
---|
966 | | - DHD_ERROR(("%s bad TLV ID : %d\n", |
---|
| 1141 | + DHD_RTT_ERR(("%s bad TLV ID : %d\n", |
---|
967 | 1142 | __FUNCTION__, p_config_param_info->tlvid)); |
---|
968 | 1143 | break; |
---|
969 | 1144 | } |
---|
970 | 1145 | |
---|
971 | 1146 | ret = bcm_pack_xtlv_entry((uint8 **) p_tlv, p_buf_space_left, |
---|
972 | | - p_config_param_info->tlvid, src_data_size, p_src_data, |
---|
| 1147 | + p_config_param_info->tlvid, src_data_size, (uint8 *)p_src_data, |
---|
973 | 1148 | BCM_XTLV_OPTION_ALIGN32); |
---|
974 | 1149 | if (ret != BCME_OK) { |
---|
975 | | - DHD_ERROR(("%s: bcm_pack_xltv_entry() failed," |
---|
| 1150 | + DHD_RTT_ERR(("%s: bcm_pack_xltv_entry() failed," |
---|
976 | 1151 | " status=%d\n", __FUNCTION__, ret)); |
---|
977 | 1152 | break; |
---|
978 | 1153 | } |
---|
979 | 1154 | |
---|
980 | 1155 | } |
---|
981 | 1156 | } |
---|
982 | | - return ret; |
---|
983 | | -} |
---|
984 | | - |
---|
985 | | -static int |
---|
986 | | -dhd_rtt_get_version(dhd_pub_t *dhd, int *out_version) |
---|
987 | | -{ |
---|
988 | | - int ret; |
---|
989 | | - ftm_subcmd_info_t subcmd_info; |
---|
990 | | - subcmd_info.name = "ver"; |
---|
991 | | - subcmd_info.cmdid = WL_PROXD_CMD_GET_VERSION; |
---|
992 | | - subcmd_info.handler = NULL; |
---|
993 | | - ret = dhd_rtt_common_get_handler(dhd, &subcmd_info, |
---|
994 | | - WL_PROXD_METHOD_FTM, WL_PROXD_SESSION_ID_GLOBAL); |
---|
995 | | - *out_version = (ret == BCME_OK) ? subcmd_info.version : 0; |
---|
996 | 1157 | return ret; |
---|
997 | 1158 | } |
---|
998 | 1159 | |
---|
.. | .. |
---|
1028 | 1189 | return dhd_rtt_common_set_handler(dhd, &subcmd_info, |
---|
1029 | 1190 | WL_PROXD_METHOD_FTM, session_id); |
---|
1030 | 1191 | } |
---|
| 1192 | +#ifdef WL_NAN |
---|
| 1193 | +int |
---|
| 1194 | +dhd_rtt_delete_nan_session(dhd_pub_t *dhd) |
---|
| 1195 | +{ |
---|
| 1196 | + struct net_device *dev = dhd_linux_get_primary_netdev(dhd); |
---|
| 1197 | + struct wireless_dev *wdev = ndev_to_wdev(dev); |
---|
| 1198 | + struct wiphy *wiphy = wdev->wiphy; |
---|
| 1199 | + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); |
---|
| 1200 | + wl_cfgnan_terminate_directed_rtt_sessions(dev, cfg); |
---|
| 1201 | + return BCME_OK; |
---|
| 1202 | +} |
---|
| 1203 | +#endif /* WL_NAN */ |
---|
| 1204 | +/* API to find out if the given Peer Mac from FTM events |
---|
| 1205 | +* is nan-peer. Based on this we will handle the SESSION_END |
---|
| 1206 | +* event. For nan-peer FTM_SESSION_END event is ignored and handled in |
---|
| 1207 | +* nan-ranging-cancel or nan-ranging-end event. |
---|
| 1208 | +*/ |
---|
| 1209 | +static bool |
---|
| 1210 | +dhd_rtt_is_nan_peer(dhd_pub_t *dhd, struct ether_addr *peer_mac) |
---|
| 1211 | +{ |
---|
| 1212 | +#ifdef WL_NAN |
---|
| 1213 | + struct net_device *dev = dhd_linux_get_primary_netdev(dhd); |
---|
| 1214 | + struct wireless_dev *wdev = ndev_to_wdev(dev); |
---|
| 1215 | + struct wiphy *wiphy = wdev->wiphy; |
---|
| 1216 | + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); |
---|
| 1217 | + nan_ranging_inst_t *ranging_inst = NULL; |
---|
| 1218 | + bool ret = FALSE; |
---|
| 1219 | + |
---|
| 1220 | + if (cfg->nan_enable == FALSE || ETHER_ISNULLADDR(peer_mac)) { |
---|
| 1221 | + goto exit; |
---|
| 1222 | + } |
---|
| 1223 | + |
---|
| 1224 | + ranging_inst = wl_cfgnan_check_for_ranging(cfg, peer_mac); |
---|
| 1225 | + if (ranging_inst) { |
---|
| 1226 | + DHD_RTT((" RTT peer is of type NAN\n")); |
---|
| 1227 | + ret = TRUE; |
---|
| 1228 | + goto exit; |
---|
| 1229 | + } |
---|
| 1230 | +exit: |
---|
| 1231 | + return ret; |
---|
| 1232 | +#else |
---|
| 1233 | + return FALSE; |
---|
| 1234 | +#endif /* WL_NAN */ |
---|
| 1235 | +} |
---|
| 1236 | + |
---|
| 1237 | +#ifdef WL_NAN |
---|
| 1238 | +static int |
---|
| 1239 | +dhd_rtt_nan_start_session(dhd_pub_t *dhd, rtt_target_info_t *rtt_target) |
---|
| 1240 | +{ |
---|
| 1241 | + s32 err = BCME_OK; |
---|
| 1242 | + struct net_device *dev = dhd_linux_get_primary_netdev(dhd); |
---|
| 1243 | + struct wireless_dev *wdev = ndev_to_wdev(dev); |
---|
| 1244 | + struct wiphy *wiphy = wdev->wiphy; |
---|
| 1245 | + struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); |
---|
| 1246 | + wl_nan_ev_rng_rpt_ind_t range_res; |
---|
| 1247 | + nan_ranging_inst_t *ranging_inst = NULL; |
---|
| 1248 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1249 | + |
---|
| 1250 | + NAN_MUTEX_LOCK(); |
---|
| 1251 | + |
---|
| 1252 | + bzero(&range_res, sizeof(range_res)); |
---|
| 1253 | + |
---|
| 1254 | + if (!rtt_status) { |
---|
| 1255 | + err = BCME_NOTENABLED; |
---|
| 1256 | + goto done; |
---|
| 1257 | + } |
---|
| 1258 | + |
---|
| 1259 | + if (!cfg->nan_enable) { /* If nan is not enabled report error */ |
---|
| 1260 | + err = BCME_NOTENABLED; |
---|
| 1261 | + goto done; |
---|
| 1262 | + } |
---|
| 1263 | + |
---|
| 1264 | + /* check if new ranging session allowed */ |
---|
| 1265 | + if (!wl_cfgnan_ranging_allowed(cfg)) { |
---|
| 1266 | + /* responder should be in progress because initiator requests are |
---|
| 1267 | + * queued in DHD. Since initiator has more proef cancel responder |
---|
| 1268 | + * sessions |
---|
| 1269 | + */ |
---|
| 1270 | + wl_cfgnan_cancel_rng_responders(dev, cfg); |
---|
| 1271 | + } |
---|
| 1272 | + |
---|
| 1273 | + ranging_inst = wl_cfgnan_get_ranging_inst(cfg, |
---|
| 1274 | + &rtt_target->addr, NAN_RANGING_ROLE_INITIATOR); |
---|
| 1275 | + if (!ranging_inst) { |
---|
| 1276 | + err = BCME_NORESOURCE; |
---|
| 1277 | + goto done; |
---|
| 1278 | + } |
---|
| 1279 | + |
---|
| 1280 | + DHD_RTT(("Trigger nan based range request\n")); |
---|
| 1281 | + err = wl_cfgnan_trigger_ranging(bcmcfg_to_prmry_ndev(cfg), |
---|
| 1282 | + cfg, ranging_inst, NULL, NAN_RANGE_REQ_CMD, TRUE); |
---|
| 1283 | + if (unlikely(err)) { |
---|
| 1284 | + goto done; |
---|
| 1285 | + } |
---|
| 1286 | + ranging_inst->range_type = RTT_TYPE_NAN_DIRECTED; |
---|
| 1287 | + ranging_inst->range_role = NAN_RANGING_ROLE_INITIATOR; |
---|
| 1288 | + /* schedule proxd timeout */ |
---|
| 1289 | + schedule_delayed_work(&rtt_status->proxd_timeout, |
---|
| 1290 | + msecs_to_jiffies(DHD_NAN_RTT_TIMER_INTERVAL_MS)); |
---|
| 1291 | +done: |
---|
| 1292 | + if (err) { /* notify failure RTT event to host */ |
---|
| 1293 | + DHD_RTT_ERR(("Failed to issue Nan Ranging Request err %d\n", err)); |
---|
| 1294 | + dhd_rtt_handle_nan_rtt_session_end(dhd, &rtt_target->addr); |
---|
| 1295 | + /* try to reset geofence */ |
---|
| 1296 | + if (ranging_inst) { |
---|
| 1297 | + wl_cfgnan_reset_geofence_ranging(cfg, ranging_inst, |
---|
| 1298 | + RTT_SCHED_DIR_TRIGGER_FAIL); |
---|
| 1299 | + } |
---|
| 1300 | + } |
---|
| 1301 | + NAN_MUTEX_UNLOCK(); |
---|
| 1302 | + return err; |
---|
| 1303 | +} |
---|
| 1304 | +#endif /* WL_NAN */ |
---|
1031 | 1305 | |
---|
1032 | 1306 | static int |
---|
1033 | 1307 | dhd_rtt_ftm_config(dhd_pub_t *dhd, wl_proxd_session_id_t session_id, |
---|
.. | .. |
---|
1042 | 1316 | uint16 buf_space_left; |
---|
1043 | 1317 | uint16 all_tlvsize; |
---|
1044 | 1318 | int ret = BCME_OK; |
---|
| 1319 | + |
---|
1045 | 1320 | subcmd_info.name = "config"; |
---|
1046 | 1321 | subcmd_info.cmdid = WL_PROXD_CMD_CONFIG; |
---|
1047 | 1322 | |
---|
.. | .. |
---|
1049 | 1324 | FTM_IOC_BUFSZ, &proxd_iovsize); |
---|
1050 | 1325 | |
---|
1051 | 1326 | if (p_proxd_iov == NULL) { |
---|
1052 | | - DHD_ERROR(("%s : failed to allocate the iovar (size :%d)\n", |
---|
| 1327 | + DHD_RTT_ERR(("%s : failed to allocate the iovar (size :%d)\n", |
---|
1053 | 1328 | __FUNCTION__, FTM_IOC_BUFSZ)); |
---|
1054 | 1329 | return BCME_NOMEM; |
---|
1055 | 1330 | } |
---|
.. | .. |
---|
1072 | 1347 | ret = dhd_iovar(dhd, 0, "proxd", (char *)p_proxd_iov, |
---|
1073 | 1348 | all_tlvsize + WL_PROXD_IOV_HDR_SIZE, NULL, 0, TRUE); |
---|
1074 | 1349 | if (ret != BCME_OK) { |
---|
1075 | | - DHD_ERROR(("%s : failed to set config \n", __FUNCTION__)); |
---|
| 1350 | + DHD_RTT_ERR(("%s : failed to set config\n", __FUNCTION__)); |
---|
1076 | 1351 | } |
---|
1077 | 1352 | } |
---|
1078 | 1353 | /* clean up */ |
---|
1079 | 1354 | kfree(p_proxd_iov); |
---|
1080 | 1355 | return ret; |
---|
1081 | 1356 | } |
---|
| 1357 | + |
---|
| 1358 | +static int |
---|
| 1359 | +dhd_rtt_get_version(dhd_pub_t *dhd, int *out_version) |
---|
| 1360 | +{ |
---|
| 1361 | + int ret; |
---|
| 1362 | + ftm_subcmd_info_t subcmd_info; |
---|
| 1363 | + subcmd_info.name = "ver"; |
---|
| 1364 | + subcmd_info.cmdid = WL_PROXD_CMD_GET_VERSION; |
---|
| 1365 | + subcmd_info.handler = NULL; |
---|
| 1366 | + ret = dhd_rtt_common_get_handler(dhd, &subcmd_info, |
---|
| 1367 | + WL_PROXD_METHOD_FTM, WL_PROXD_SESSION_ID_GLOBAL); |
---|
| 1368 | + *out_version = (ret == BCME_OK) ? subcmd_info.version : 0; |
---|
| 1369 | + return ret; |
---|
| 1370 | +} |
---|
| 1371 | +#endif /* WL_CFG80211 */ |
---|
| 1372 | + |
---|
1082 | 1373 | chanspec_t |
---|
1083 | 1374 | dhd_rtt_convert_to_chspec(wifi_channel_info_t channel) |
---|
1084 | 1375 | { |
---|
.. | .. |
---|
1108 | 1399 | chanspec = wf_chspec_80(center_chan, primary_chan); |
---|
1109 | 1400 | break; |
---|
1110 | 1401 | default: |
---|
1111 | | - DHD_ERROR(("doesn't support this bandwith : %d", channel.width)); |
---|
| 1402 | + DHD_RTT_ERR(("doesn't support this bandwith : %d", channel.width)); |
---|
1112 | 1403 | bw = -1; |
---|
1113 | 1404 | break; |
---|
1114 | 1405 | } |
---|
.. | .. |
---|
1129 | 1420 | { |
---|
1130 | 1421 | int err = BCME_OK; |
---|
1131 | 1422 | int idx; |
---|
1132 | | - rtt_status_info_t *rtt_status; |
---|
1133 | | - NULL_CHECK(params, "params is NULL", err); |
---|
| 1423 | + rtt_status_info_t *rtt_status = NULL; |
---|
| 1424 | + struct net_device *dev = NULL; |
---|
1134 | 1425 | |
---|
| 1426 | + NULL_CHECK(params, "params is NULL", err); |
---|
1135 | 1427 | NULL_CHECK(dhd, "dhd is NULL", err); |
---|
| 1428 | + |
---|
| 1429 | + dev = dhd_linux_get_primary_netdev(dhd); |
---|
1136 | 1430 | rtt_status = GET_RTTSTATE(dhd); |
---|
1137 | 1431 | NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
| 1432 | + NULL_CHECK(dev, "dev is NULL", err); |
---|
| 1433 | + |
---|
1138 | 1434 | if (!HAS_11MC_CAP(rtt_status->rtt_capa.proto)) { |
---|
1139 | | - DHD_ERROR(("doesn't support RTT \n")); |
---|
1140 | | - return BCME_ERROR; |
---|
| 1435 | + DHD_RTT_ERR(("doesn't support RTT \n")); |
---|
| 1436 | + err = BCME_ERROR; |
---|
| 1437 | + goto exit; |
---|
1141 | 1438 | } |
---|
1142 | | - if (rtt_status->status != RTT_STOPPED) { |
---|
1143 | | - DHD_ERROR(("rtt is already started\n")); |
---|
1144 | | - return BCME_BUSY; |
---|
1145 | | - } |
---|
| 1439 | + |
---|
1146 | 1440 | DHD_RTT(("%s enter\n", __FUNCTION__)); |
---|
1147 | 1441 | |
---|
| 1442 | + if (params->rtt_target_cnt > 0) { |
---|
| 1443 | +#ifdef WL_NAN |
---|
| 1444 | + /* cancel ongoing geofence RTT if there */ |
---|
| 1445 | + if ((err = wl_cfgnan_suspend_geofence_rng_session(dev, |
---|
| 1446 | + NULL, RTT_GEO_SUSPN_HOST_DIR_RTT_TRIG, 0)) != BCME_OK) { |
---|
| 1447 | + goto exit; |
---|
| 1448 | + } |
---|
| 1449 | +#endif /* WL_NAN */ |
---|
| 1450 | + } else { |
---|
| 1451 | + err = BCME_BADARG; |
---|
| 1452 | + goto exit; |
---|
| 1453 | + } |
---|
| 1454 | + |
---|
| 1455 | + mutex_lock(&rtt_status->rtt_mutex); |
---|
| 1456 | + if (rtt_status->status != RTT_STOPPED) { |
---|
| 1457 | + DHD_RTT_ERR(("rtt is already started\n")); |
---|
| 1458 | + err = BCME_BUSY; |
---|
| 1459 | + goto exit; |
---|
| 1460 | + } |
---|
1148 | 1461 | memset(rtt_status->rtt_config.target_info, 0, TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT)); |
---|
1149 | 1462 | rtt_status->rtt_config.rtt_target_cnt = params->rtt_target_cnt; |
---|
1150 | 1463 | memcpy(rtt_status->rtt_config.target_info, |
---|
1151 | 1464 | params->target_info, TARGET_INFO_SIZE(params->rtt_target_cnt)); |
---|
1152 | 1465 | rtt_status->status = RTT_STARTED; |
---|
| 1466 | + DHD_RTT_MEM(("dhd_rtt_set_cfg: RTT Started, target_cnt = %d\n", params->rtt_target_cnt)); |
---|
1153 | 1467 | /* start to measure RTT from first device */ |
---|
1154 | 1468 | /* find next target to trigger RTT */ |
---|
1155 | 1469 | for (idx = rtt_status->cur_idx; idx < rtt_status->rtt_config.rtt_target_cnt; idx++) { |
---|
.. | .. |
---|
1164 | 1478 | } |
---|
1165 | 1479 | if (idx < rtt_status->rtt_config.rtt_target_cnt) { |
---|
1166 | 1480 | DHD_RTT(("rtt_status->cur_idx : %d\n", rtt_status->cur_idx)); |
---|
| 1481 | + rtt_status->rtt_sched_reason = RTT_SCHED_HOST_TRIGGER; |
---|
1167 | 1482 | schedule_work(&rtt_status->work); |
---|
1168 | 1483 | } |
---|
| 1484 | +exit: |
---|
| 1485 | + mutex_unlock(&rtt_status->rtt_mutex); |
---|
1169 | 1486 | return err; |
---|
| 1487 | +} |
---|
| 1488 | + |
---|
| 1489 | +#define GEOFENCE_RTT_LOCK(rtt_status) mutex_lock(&(rtt_status)->geofence_mutex) |
---|
| 1490 | +#define GEOFENCE_RTT_UNLOCK(rtt_status) mutex_unlock(&(rtt_status)->geofence_mutex) |
---|
| 1491 | + |
---|
| 1492 | +#ifdef WL_NAN |
---|
| 1493 | +/* sets geofence role concurrency state TRUE/FALSE */ |
---|
| 1494 | +void |
---|
| 1495 | +dhd_rtt_set_role_concurrency_state(dhd_pub_t *dhd, bool state) |
---|
| 1496 | +{ |
---|
| 1497 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1498 | + if (!rtt_status) { |
---|
| 1499 | + return; |
---|
| 1500 | + } |
---|
| 1501 | + GEOFENCE_RTT_LOCK(rtt_status); |
---|
| 1502 | + rtt_status->geofence_cfg.role_concurr_state = state; |
---|
| 1503 | + GEOFENCE_RTT_UNLOCK(rtt_status); |
---|
| 1504 | +} |
---|
| 1505 | + |
---|
| 1506 | +/* returns TRUE if geofence role concurrency constraint exists */ |
---|
| 1507 | +bool |
---|
| 1508 | +dhd_rtt_get_role_concurrency_state(dhd_pub_t *dhd) |
---|
| 1509 | +{ |
---|
| 1510 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1511 | + if (!rtt_status) { |
---|
| 1512 | + return FALSE; |
---|
| 1513 | + } |
---|
| 1514 | + return rtt_status->geofence_cfg.role_concurr_state; |
---|
| 1515 | +} |
---|
| 1516 | + |
---|
| 1517 | +int8 |
---|
| 1518 | +dhd_rtt_get_geofence_target_cnt(dhd_pub_t *dhd) |
---|
| 1519 | +{ |
---|
| 1520 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1521 | + if (!rtt_status) { |
---|
| 1522 | + return 0; |
---|
| 1523 | + } |
---|
| 1524 | + return rtt_status->geofence_cfg.geofence_target_cnt; |
---|
| 1525 | +} |
---|
| 1526 | + |
---|
| 1527 | +/* sets geofence rtt state TRUE/FALSE */ |
---|
| 1528 | +void |
---|
| 1529 | +dhd_rtt_set_geofence_rtt_state(dhd_pub_t *dhd, bool state) |
---|
| 1530 | +{ |
---|
| 1531 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1532 | + if (!rtt_status) { |
---|
| 1533 | + return; |
---|
| 1534 | + } |
---|
| 1535 | + GEOFENCE_RTT_LOCK(rtt_status); |
---|
| 1536 | + rtt_status->geofence_cfg.rtt_in_progress = state; |
---|
| 1537 | + GEOFENCE_RTT_UNLOCK(rtt_status); |
---|
| 1538 | +} |
---|
| 1539 | + |
---|
| 1540 | +/* returns TRUE if geofence rtt is in progress */ |
---|
| 1541 | +bool |
---|
| 1542 | +dhd_rtt_get_geofence_rtt_state(dhd_pub_t *dhd) |
---|
| 1543 | +{ |
---|
| 1544 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1545 | + |
---|
| 1546 | + if (!rtt_status) { |
---|
| 1547 | + return FALSE; |
---|
| 1548 | + } |
---|
| 1549 | + |
---|
| 1550 | + return rtt_status->geofence_cfg.rtt_in_progress; |
---|
| 1551 | +} |
---|
| 1552 | + |
---|
| 1553 | +/* returns geofence RTT target list Head */ |
---|
| 1554 | +rtt_geofence_target_info_t* |
---|
| 1555 | +dhd_rtt_get_geofence_target_head(dhd_pub_t *dhd) |
---|
| 1556 | +{ |
---|
| 1557 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1558 | + rtt_geofence_target_info_t* head = NULL; |
---|
| 1559 | + |
---|
| 1560 | + if (!rtt_status) { |
---|
| 1561 | + return NULL; |
---|
| 1562 | + } |
---|
| 1563 | + |
---|
| 1564 | + if (rtt_status->geofence_cfg.geofence_target_cnt) { |
---|
| 1565 | + head = &rtt_status->geofence_cfg.geofence_target_info[0]; |
---|
| 1566 | + } |
---|
| 1567 | + |
---|
| 1568 | + return head; |
---|
| 1569 | +} |
---|
| 1570 | + |
---|
| 1571 | +int8 |
---|
| 1572 | +dhd_rtt_get_geofence_cur_target_idx(dhd_pub_t *dhd) |
---|
| 1573 | +{ |
---|
| 1574 | + int8 target_cnt = 0, cur_idx = DHD_RTT_INVALID_TARGET_INDEX; |
---|
| 1575 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1576 | + |
---|
| 1577 | + if (!rtt_status) { |
---|
| 1578 | + goto exit; |
---|
| 1579 | + } |
---|
| 1580 | + |
---|
| 1581 | + target_cnt = rtt_status->geofence_cfg.geofence_target_cnt; |
---|
| 1582 | + if (target_cnt == 0) { |
---|
| 1583 | + goto exit; |
---|
| 1584 | + } |
---|
| 1585 | + |
---|
| 1586 | + cur_idx = rtt_status->geofence_cfg.cur_target_idx; |
---|
| 1587 | + ASSERT(cur_idx <= target_cnt); |
---|
| 1588 | + |
---|
| 1589 | +exit: |
---|
| 1590 | + return cur_idx; |
---|
| 1591 | +} |
---|
| 1592 | + |
---|
| 1593 | +void |
---|
| 1594 | +dhd_rtt_move_geofence_cur_target_idx_to_next(dhd_pub_t *dhd) |
---|
| 1595 | +{ |
---|
| 1596 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1597 | + |
---|
| 1598 | + if (!rtt_status) { |
---|
| 1599 | + return; |
---|
| 1600 | + } |
---|
| 1601 | + |
---|
| 1602 | + if (rtt_status->geofence_cfg.geofence_target_cnt == 0) { |
---|
| 1603 | + /* Invalidate current idx if no targets */ |
---|
| 1604 | + rtt_status->geofence_cfg.cur_target_idx = |
---|
| 1605 | + DHD_RTT_INVALID_TARGET_INDEX; |
---|
| 1606 | + /* Cancel pending retry timer if any */ |
---|
| 1607 | + if (delayed_work_pending(&rtt_status->rtt_retry_timer)) { |
---|
| 1608 | + cancel_delayed_work(&rtt_status->rtt_retry_timer); |
---|
| 1609 | + } |
---|
| 1610 | + return; |
---|
| 1611 | + } |
---|
| 1612 | + rtt_status->geofence_cfg.cur_target_idx++; |
---|
| 1613 | + |
---|
| 1614 | + if (rtt_status->geofence_cfg.cur_target_idx >= |
---|
| 1615 | + rtt_status->geofence_cfg.geofence_target_cnt) { |
---|
| 1616 | + /* Reset once all targets done */ |
---|
| 1617 | + rtt_status->geofence_cfg.cur_target_idx = 0; |
---|
| 1618 | + } |
---|
| 1619 | +} |
---|
| 1620 | + |
---|
| 1621 | +/* returns geofence current RTT target */ |
---|
| 1622 | +rtt_geofence_target_info_t* |
---|
| 1623 | +dhd_rtt_get_geofence_current_target(dhd_pub_t *dhd) |
---|
| 1624 | +{ |
---|
| 1625 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1626 | + rtt_geofence_target_info_t* cur_target = NULL; |
---|
| 1627 | + int cur_idx = 0; |
---|
| 1628 | + |
---|
| 1629 | + if (!rtt_status) { |
---|
| 1630 | + return NULL; |
---|
| 1631 | + } |
---|
| 1632 | + |
---|
| 1633 | + cur_idx = dhd_rtt_get_geofence_cur_target_idx(dhd); |
---|
| 1634 | + if (cur_idx >= 0) { |
---|
| 1635 | + cur_target = &rtt_status->geofence_cfg.geofence_target_info[cur_idx]; |
---|
| 1636 | + } |
---|
| 1637 | + |
---|
| 1638 | + return cur_target; |
---|
| 1639 | +} |
---|
| 1640 | + |
---|
| 1641 | +/* returns geofence target from list for the peer */ |
---|
| 1642 | +rtt_geofence_target_info_t* |
---|
| 1643 | +dhd_rtt_get_geofence_target(dhd_pub_t *dhd, struct ether_addr* peer_addr, int8 *index) |
---|
| 1644 | +{ |
---|
| 1645 | + int8 i; |
---|
| 1646 | + rtt_status_info_t *rtt_status; |
---|
| 1647 | + int target_cnt; |
---|
| 1648 | + rtt_geofence_target_info_t *geofence_target_info, *tgt = NULL; |
---|
| 1649 | + |
---|
| 1650 | + rtt_status = GET_RTTSTATE(dhd); |
---|
| 1651 | + |
---|
| 1652 | + if (!rtt_status) { |
---|
| 1653 | + return NULL; |
---|
| 1654 | + } |
---|
| 1655 | + |
---|
| 1656 | + target_cnt = rtt_status->geofence_cfg.geofence_target_cnt; |
---|
| 1657 | + geofence_target_info = rtt_status->geofence_cfg.geofence_target_info; |
---|
| 1658 | + |
---|
| 1659 | + /* Loop through to find target */ |
---|
| 1660 | + for (i = 0; i < target_cnt; i++) { |
---|
| 1661 | + if (geofence_target_info[i].valid == FALSE) { |
---|
| 1662 | + break; |
---|
| 1663 | + } |
---|
| 1664 | + if (!memcmp(peer_addr, &geofence_target_info[i].peer_addr, |
---|
| 1665 | + ETHER_ADDR_LEN)) { |
---|
| 1666 | + *index = i; |
---|
| 1667 | + tgt = &geofence_target_info[i]; |
---|
| 1668 | + } |
---|
| 1669 | + } |
---|
| 1670 | + if (!tgt) { |
---|
| 1671 | + DHD_RTT(("dhd_rtt_get_geofence_target: Target not found in list," |
---|
| 1672 | + " MAC ADDR: "MACDBG" \n", MAC2STRDBG(peer_addr))); |
---|
| 1673 | + } |
---|
| 1674 | + return tgt; |
---|
| 1675 | +} |
---|
| 1676 | + |
---|
| 1677 | +/* add geofence target to the target list */ |
---|
| 1678 | +int |
---|
| 1679 | +dhd_rtt_add_geofence_target(dhd_pub_t *dhd, rtt_geofence_target_info_t *target) |
---|
| 1680 | +{ |
---|
| 1681 | + int err = BCME_OK; |
---|
| 1682 | + rtt_status_info_t *rtt_status; |
---|
| 1683 | + rtt_geofence_target_info_t *geofence_target_info; |
---|
| 1684 | + int8 geofence_target_cnt, index; |
---|
| 1685 | + |
---|
| 1686 | + NULL_CHECK(dhd, "dhd is NULL", err); |
---|
| 1687 | + rtt_status = GET_RTTSTATE(dhd); |
---|
| 1688 | + NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
| 1689 | + |
---|
| 1690 | + GEOFENCE_RTT_LOCK(rtt_status); |
---|
| 1691 | + |
---|
| 1692 | + /* Get the geofence_target via peer addr, index param is dumm here */ |
---|
| 1693 | + geofence_target_info = dhd_rtt_get_geofence_target(dhd, &target->peer_addr, &index); |
---|
| 1694 | + if (geofence_target_info) { |
---|
| 1695 | + DHD_RTT(("Duplicate geofencing RTT add request dropped\n")); |
---|
| 1696 | + err = BCME_OK; |
---|
| 1697 | + goto exit; |
---|
| 1698 | + } |
---|
| 1699 | + |
---|
| 1700 | + geofence_target_cnt = rtt_status->geofence_cfg.geofence_target_cnt; |
---|
| 1701 | + if (geofence_target_cnt >= RTT_MAX_GEOFENCE_TARGET_CNT) { |
---|
| 1702 | + DHD_RTT(("Queue full, Geofencing RTT add request dropped\n")); |
---|
| 1703 | + err = BCME_NORESOURCE; |
---|
| 1704 | + goto exit; |
---|
| 1705 | + } |
---|
| 1706 | + |
---|
| 1707 | + /* Add Geofence RTT request and increment target count */ |
---|
| 1708 | + geofence_target_info = rtt_status->geofence_cfg.geofence_target_info; |
---|
| 1709 | + /* src and dest buffer len same, pointers of same DS statically allocated */ |
---|
| 1710 | + (void)memcpy_s(&geofence_target_info[geofence_target_cnt], |
---|
| 1711 | + sizeof(geofence_target_info[geofence_target_cnt]), target, |
---|
| 1712 | + sizeof(*target)); |
---|
| 1713 | + geofence_target_info[geofence_target_cnt].valid = TRUE; |
---|
| 1714 | + rtt_status->geofence_cfg.geofence_target_cnt++; |
---|
| 1715 | + if (rtt_status->geofence_cfg.geofence_target_cnt == 1) { |
---|
| 1716 | + /* Adding first target */ |
---|
| 1717 | + rtt_status->geofence_cfg.cur_target_idx = 0; |
---|
| 1718 | + } |
---|
| 1719 | + |
---|
| 1720 | +exit: |
---|
| 1721 | + GEOFENCE_RTT_UNLOCK(rtt_status); |
---|
| 1722 | + return err; |
---|
| 1723 | +} |
---|
| 1724 | + |
---|
| 1725 | +/* removes geofence target from the target list */ |
---|
| 1726 | +int |
---|
| 1727 | +dhd_rtt_remove_geofence_target(dhd_pub_t *dhd, struct ether_addr *peer_addr) |
---|
| 1728 | +{ |
---|
| 1729 | + int err = BCME_OK; |
---|
| 1730 | + rtt_status_info_t *rtt_status; |
---|
| 1731 | + rtt_geofence_target_info_t *geofence_target_info; |
---|
| 1732 | + int8 geofence_target_cnt, j, index = 0; |
---|
| 1733 | + |
---|
| 1734 | + NULL_CHECK(dhd, "dhd is NULL", err); |
---|
| 1735 | + rtt_status = GET_RTTSTATE(dhd); |
---|
| 1736 | + NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
| 1737 | + |
---|
| 1738 | + GEOFENCE_RTT_LOCK(rtt_status); |
---|
| 1739 | + |
---|
| 1740 | + geofence_target_cnt = dhd_rtt_get_geofence_target_cnt(dhd); |
---|
| 1741 | + if (geofence_target_cnt == 0) { |
---|
| 1742 | + DHD_RTT(("Queue Empty, Geofencing RTT remove request dropped\n")); |
---|
| 1743 | + ASSERT(0); |
---|
| 1744 | + goto exit; |
---|
| 1745 | + } |
---|
| 1746 | + |
---|
| 1747 | + /* Get the geofence_target via peer addr */ |
---|
| 1748 | + geofence_target_info = dhd_rtt_get_geofence_target(dhd, peer_addr, &index); |
---|
| 1749 | + if (geofence_target_info == NULL) { |
---|
| 1750 | + DHD_RTT(("Geofencing RTT target not found, remove request dropped\n")); |
---|
| 1751 | + err = BCME_NOTFOUND; |
---|
| 1752 | + goto exit; |
---|
| 1753 | + } |
---|
| 1754 | + |
---|
| 1755 | + /* left shift all the valid entries, as we dont keep holes in list */ |
---|
| 1756 | + for (j = index; (j+1) < geofence_target_cnt; j++) { |
---|
| 1757 | + if (geofence_target_info[j].valid == TRUE) { |
---|
| 1758 | + /* |
---|
| 1759 | + * src and dest buffer len same, pointers of same DS |
---|
| 1760 | + * statically allocated |
---|
| 1761 | + */ |
---|
| 1762 | + (void)memcpy_s(&geofence_target_info[j], sizeof(geofence_target_info[j]), |
---|
| 1763 | + &geofence_target_info[j + 1], |
---|
| 1764 | + sizeof(geofence_target_info[j + 1])); |
---|
| 1765 | + } else { |
---|
| 1766 | + break; |
---|
| 1767 | + } |
---|
| 1768 | + } |
---|
| 1769 | + rtt_status->geofence_cfg.geofence_target_cnt--; |
---|
| 1770 | + if ((rtt_status->geofence_cfg.geofence_target_cnt == 0) || |
---|
| 1771 | + (index == rtt_status->geofence_cfg.cur_target_idx)) { |
---|
| 1772 | + /* Move cur_idx to next target */ |
---|
| 1773 | + dhd_rtt_move_geofence_cur_target_idx_to_next(dhd); |
---|
| 1774 | + } else if (index < rtt_status->geofence_cfg.cur_target_idx) { |
---|
| 1775 | + /* Decrement cur index if cur target position changed */ |
---|
| 1776 | + rtt_status->geofence_cfg.cur_target_idx--; |
---|
| 1777 | + } |
---|
| 1778 | + |
---|
| 1779 | +exit: |
---|
| 1780 | + GEOFENCE_RTT_UNLOCK(rtt_status); |
---|
| 1781 | + return err; |
---|
| 1782 | +} |
---|
| 1783 | + |
---|
| 1784 | +/* deletes/empty geofence target list */ |
---|
| 1785 | +int |
---|
| 1786 | +dhd_rtt_delete_geofence_target_list(dhd_pub_t *dhd) |
---|
| 1787 | +{ |
---|
| 1788 | + rtt_status_info_t *rtt_status; |
---|
| 1789 | + |
---|
| 1790 | + int err = BCME_OK; |
---|
| 1791 | + |
---|
| 1792 | + NULL_CHECK(dhd, "dhd is NULL", err); |
---|
| 1793 | + rtt_status = GET_RTTSTATE(dhd); |
---|
| 1794 | + NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
| 1795 | + GEOFENCE_RTT_LOCK(rtt_status); |
---|
| 1796 | + memset_s(&rtt_status->geofence_cfg, sizeof(rtt_geofence_cfg_t), |
---|
| 1797 | + 0, sizeof(rtt_geofence_cfg_t)); |
---|
| 1798 | + GEOFENCE_RTT_UNLOCK(rtt_status); |
---|
| 1799 | + return err; |
---|
| 1800 | +} |
---|
| 1801 | + |
---|
| 1802 | +int |
---|
| 1803 | +dhd_rtt_sched_geofencing_target(dhd_pub_t *dhd) |
---|
| 1804 | +{ |
---|
| 1805 | + rtt_geofence_target_info_t *geofence_target_info; |
---|
| 1806 | + struct net_device *dev = dhd_linux_get_primary_netdev(dhd); |
---|
| 1807 | + int ret = BCME_OK; |
---|
| 1808 | + bool geofence_state; |
---|
| 1809 | + bool role_concurrency_state; |
---|
| 1810 | + u8 rtt_invalid_reason = RTT_STATE_VALID; |
---|
| 1811 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 1812 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1813 | + |
---|
| 1814 | + NAN_MUTEX_LOCK(); |
---|
| 1815 | + |
---|
| 1816 | + if ((cfg->nan_init_state == FALSE) || |
---|
| 1817 | + (cfg->nan_enable == FALSE)) { |
---|
| 1818 | + ret = BCME_NOTENABLED; |
---|
| 1819 | + goto done; |
---|
| 1820 | + } |
---|
| 1821 | + geofence_state = dhd_rtt_get_geofence_rtt_state(dhd); |
---|
| 1822 | + role_concurrency_state = dhd_rtt_get_role_concurrency_state(dhd); |
---|
| 1823 | + |
---|
| 1824 | + DHD_RTT_ERR(("dhd_rtt_sched_geofencing_target: sched_reason = %d\n", |
---|
| 1825 | + rtt_status->rtt_sched_reason)); |
---|
| 1826 | + |
---|
| 1827 | + if (geofence_state == TRUE || role_concurrency_state == TRUE) { |
---|
| 1828 | + ret = BCME_ERROR; |
---|
| 1829 | + DHD_RTT_ERR(("geofencing constraint , sched request dropped," |
---|
| 1830 | + " geofence_state = %d, role_concurrency_state = %d\n", |
---|
| 1831 | + geofence_state, role_concurrency_state)); |
---|
| 1832 | + goto done; |
---|
| 1833 | + } |
---|
| 1834 | + |
---|
| 1835 | + /* Get current geofencing target */ |
---|
| 1836 | + geofence_target_info = dhd_rtt_get_geofence_current_target(dhd); |
---|
| 1837 | + |
---|
| 1838 | + /* call cfg API for trigerring geofencing RTT */ |
---|
| 1839 | + if (geofence_target_info) { |
---|
| 1840 | + /* check for dp/others concurrency */ |
---|
| 1841 | + rtt_invalid_reason = dhd_rtt_invalid_states(dev, |
---|
| 1842 | + &geofence_target_info->peer_addr); |
---|
| 1843 | + if (rtt_invalid_reason != RTT_STATE_VALID) { |
---|
| 1844 | + ret = BCME_BUSY; |
---|
| 1845 | + DHD_RTT_ERR(("DRV State is not valid for RTT, " |
---|
| 1846 | + "invalid_state = %d\n", rtt_invalid_reason)); |
---|
| 1847 | + goto done; |
---|
| 1848 | + } |
---|
| 1849 | + |
---|
| 1850 | + ret = wl_cfgnan_trigger_geofencing_ranging(dev, |
---|
| 1851 | + &geofence_target_info->peer_addr); |
---|
| 1852 | + if (ret == BCME_OK) { |
---|
| 1853 | + dhd_rtt_set_geofence_rtt_state(dhd, TRUE); |
---|
| 1854 | + } |
---|
| 1855 | + } else { |
---|
| 1856 | + DHD_RTT(("No RTT target to schedule\n")); |
---|
| 1857 | + ret = BCME_NOTFOUND; |
---|
| 1858 | + } |
---|
| 1859 | + |
---|
| 1860 | +done: |
---|
| 1861 | + NAN_MUTEX_UNLOCK(); |
---|
| 1862 | + return ret; |
---|
| 1863 | +} |
---|
| 1864 | +#endif /* WL_NAN */ |
---|
| 1865 | + |
---|
| 1866 | +#ifdef WL_CFG80211 |
---|
| 1867 | +#ifdef WL_NAN |
---|
| 1868 | +static void |
---|
| 1869 | +dhd_rtt_retry(dhd_pub_t *dhd) |
---|
| 1870 | +{ |
---|
| 1871 | + struct net_device *dev = dhd_linux_get_primary_netdev(dhd); |
---|
| 1872 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 1873 | + rtt_geofence_target_info_t *geofence_target = NULL; |
---|
| 1874 | + nan_ranging_inst_t *ranging_inst = NULL; |
---|
| 1875 | + |
---|
| 1876 | + geofence_target = dhd_rtt_get_geofence_current_target(dhd); |
---|
| 1877 | + if (!geofence_target) { |
---|
| 1878 | + DHD_RTT(("dhd_rtt_retry: geofence target null\n")); |
---|
| 1879 | + goto exit; |
---|
| 1880 | + } |
---|
| 1881 | + ranging_inst = wl_cfgnan_get_ranging_inst(cfg, |
---|
| 1882 | + &geofence_target->peer_addr, NAN_RANGING_ROLE_INITIATOR); |
---|
| 1883 | + if (!ranging_inst) { |
---|
| 1884 | + DHD_RTT(("dhd_rtt_retry: ranging instance null\n")); |
---|
| 1885 | + goto exit; |
---|
| 1886 | + } |
---|
| 1887 | + wl_cfgnan_reset_geofence_ranging(cfg, |
---|
| 1888 | + ranging_inst, RTT_SCHED_RTT_RETRY_GEOFENCE); |
---|
| 1889 | + |
---|
| 1890 | +exit: |
---|
| 1891 | + return; |
---|
| 1892 | +} |
---|
| 1893 | + |
---|
| 1894 | +static void |
---|
| 1895 | +dhd_rtt_retry_work(struct work_struct *work) |
---|
| 1896 | +{ |
---|
| 1897 | + rtt_status_info_t *rtt_status = NULL; |
---|
| 1898 | + dhd_pub_t *dhd = NULL; |
---|
| 1899 | + struct net_device *dev = NULL; |
---|
| 1900 | + struct bcm_cfg80211 *cfg = NULL; |
---|
| 1901 | + |
---|
| 1902 | +#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) |
---|
| 1903 | +#pragma GCC diagnostic push |
---|
| 1904 | +#pragma GCC diagnostic ignored "-Wcast-qual" |
---|
| 1905 | +#endif // endif |
---|
| 1906 | + rtt_status = container_of(work, rtt_status_info_t, proxd_timeout.work); |
---|
| 1907 | +#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) |
---|
| 1908 | +#pragma GCC diagnostic pop |
---|
| 1909 | +#endif // endif |
---|
| 1910 | + |
---|
| 1911 | + dhd = rtt_status->dhd; |
---|
| 1912 | + if (dhd == NULL) { |
---|
| 1913 | + DHD_RTT_ERR(("%s : dhd is NULL\n", __FUNCTION__)); |
---|
| 1914 | + goto exit; |
---|
| 1915 | + } |
---|
| 1916 | + dev = dhd_linux_get_primary_netdev(dhd); |
---|
| 1917 | + cfg = wl_get_cfg(dev); |
---|
| 1918 | + |
---|
| 1919 | + NAN_MUTEX_LOCK(); |
---|
| 1920 | + mutex_lock(&rtt_status->rtt_mutex); |
---|
| 1921 | + (void) dhd_rtt_retry(dhd); |
---|
| 1922 | + mutex_unlock(&rtt_status->rtt_mutex); |
---|
| 1923 | + NAN_MUTEX_UNLOCK(); |
---|
| 1924 | + |
---|
| 1925 | +exit: |
---|
| 1926 | + return; |
---|
| 1927 | +} |
---|
| 1928 | +#endif /* WL_NAN */ |
---|
| 1929 | + |
---|
| 1930 | +/* |
---|
| 1931 | + * Return zero (0) |
---|
| 1932 | + * for valid RTT state |
---|
| 1933 | + * means if RTT is applicable |
---|
| 1934 | + */ |
---|
| 1935 | +uint8 |
---|
| 1936 | +dhd_rtt_invalid_states(struct net_device *ndev, struct ether_addr *peer_addr) |
---|
| 1937 | +{ |
---|
| 1938 | + uint8 invalid_reason = RTT_STATE_VALID; |
---|
| 1939 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 1940 | + |
---|
| 1941 | + UNUSED_PARAMETER(cfg); |
---|
| 1942 | + UNUSED_PARAMETER(invalid_reason); |
---|
| 1943 | + |
---|
| 1944 | + /* Make sure peer addr is not NULL in caller */ |
---|
| 1945 | + ASSERT(peer_addr); |
---|
| 1946 | + /* |
---|
| 1947 | + * Keep adding prohibited drv states here |
---|
| 1948 | + * Only generic conditions which block |
---|
| 1949 | + * All RTTs like NDP connection |
---|
| 1950 | + */ |
---|
| 1951 | + |
---|
| 1952 | +#ifdef WL_NAN |
---|
| 1953 | + if (wl_cfgnan_data_dp_exists_with_peer(cfg, peer_addr)) { |
---|
| 1954 | + invalid_reason = RTT_STATE_INV_REASON_NDP_EXIST; |
---|
| 1955 | + DHD_RTT(("NDP in progress/connected, RTT prohibited\n")); |
---|
| 1956 | + goto exit; |
---|
| 1957 | + } |
---|
| 1958 | +#endif /* WL_NAN */ |
---|
| 1959 | + |
---|
| 1960 | + /* Remove below #defines once more exit calls come */ |
---|
| 1961 | +#ifdef WL_NAN |
---|
| 1962 | +exit: |
---|
| 1963 | +#endif /* WL_NAN */ |
---|
| 1964 | + return invalid_reason; |
---|
| 1965 | +} |
---|
| 1966 | +#endif /* WL_CFG80211 */ |
---|
| 1967 | + |
---|
| 1968 | +void |
---|
| 1969 | +dhd_rtt_schedule_rtt_work_thread(dhd_pub_t *dhd, int sched_reason) |
---|
| 1970 | +{ |
---|
| 1971 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 1972 | + if (rtt_status == NULL) { |
---|
| 1973 | + ASSERT(0); |
---|
| 1974 | + } else { |
---|
| 1975 | + rtt_status->rtt_sched_reason = sched_reason; |
---|
| 1976 | + schedule_work(&rtt_status->work); |
---|
| 1977 | + } |
---|
| 1978 | + return; |
---|
1170 | 1979 | } |
---|
1171 | 1980 | |
---|
1172 | 1981 | int |
---|
1173 | 1982 | dhd_rtt_stop(dhd_pub_t *dhd, struct ether_addr *mac_list, int mac_cnt) |
---|
1174 | 1983 | { |
---|
1175 | 1984 | int err = BCME_OK; |
---|
| 1985 | +#ifdef WL_CFG80211 |
---|
1176 | 1986 | int i = 0, j = 0; |
---|
1177 | 1987 | rtt_status_info_t *rtt_status; |
---|
1178 | 1988 | rtt_results_header_t *entry, *next; |
---|
.. | .. |
---|
1183 | 1993 | rtt_status = GET_RTTSTATE(dhd); |
---|
1184 | 1994 | NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
1185 | 1995 | if (rtt_status->status == RTT_STOPPED) { |
---|
1186 | | - DHD_ERROR(("rtt is not started\n")); |
---|
| 1996 | + DHD_RTT_ERR(("rtt is not started\n")); |
---|
1187 | 1997 | return BCME_OK; |
---|
1188 | 1998 | } |
---|
1189 | 1999 | DHD_RTT(("%s enter\n", __FUNCTION__)); |
---|
.. | .. |
---|
1203 | 2013 | /* remove the rtt results in cache */ |
---|
1204 | 2014 | if (!list_empty(&rtt_status->rtt_results_cache)) { |
---|
1205 | 2015 | /* Iterate rtt_results_header list */ |
---|
| 2016 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
1206 | 2017 | list_for_each_entry_safe(entry, next, |
---|
1207 | 2018 | &rtt_status->rtt_results_cache, list) { |
---|
1208 | 2019 | list_del(&entry->list); |
---|
.. | .. |
---|
1214 | 2025 | } |
---|
1215 | 2026 | kfree(entry); |
---|
1216 | 2027 | } |
---|
| 2028 | + GCC_DIAGNOSTIC_POP(); |
---|
1217 | 2029 | } |
---|
1218 | 2030 | /* send the rtt complete event to wake up the user process */ |
---|
| 2031 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
1219 | 2032 | list_for_each_entry(iter, &rtt_status->noti_fn_list, list) { |
---|
| 2033 | + GCC_DIAGNOSTIC_POP(); |
---|
1220 | 2034 | iter->noti_fn(iter->ctx, &rtt_status->rtt_results_cache); |
---|
1221 | 2035 | } |
---|
1222 | | - |
---|
1223 | 2036 | /* reinitialize the HEAD */ |
---|
1224 | 2037 | INIT_LIST_HEAD(&rtt_status->rtt_results_cache); |
---|
1225 | 2038 | /* clear information for rtt_config */ |
---|
.. | .. |
---|
1227 | 2040 | memset(rtt_status->rtt_config.target_info, 0, |
---|
1228 | 2041 | TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT)); |
---|
1229 | 2042 | rtt_status->cur_idx = 0; |
---|
| 2043 | + /* Cancel pending proxd timeout work if any */ |
---|
| 2044 | + if (delayed_work_pending(&rtt_status->proxd_timeout)) { |
---|
| 2045 | + cancel_delayed_work(&rtt_status->proxd_timeout); |
---|
| 2046 | + } |
---|
1230 | 2047 | dhd_rtt_delete_session(dhd, FTM_DEFAULT_SESSION); |
---|
| 2048 | +#ifdef WL_NAN |
---|
| 2049 | + dhd_rtt_delete_nan_session(dhd); |
---|
| 2050 | +#endif /* WL_NAN */ |
---|
1231 | 2051 | dhd_rtt_ftm_enable(dhd, FALSE); |
---|
1232 | 2052 | } |
---|
1233 | 2053 | mutex_unlock(&rtt_status->rtt_mutex); |
---|
| 2054 | +#endif /* WL_CFG80211 */ |
---|
1234 | 2055 | return err; |
---|
| 2056 | +} |
---|
| 2057 | + |
---|
| 2058 | +#ifdef WL_CFG80211 |
---|
| 2059 | +static void |
---|
| 2060 | +dhd_rtt_timeout(dhd_pub_t *dhd) |
---|
| 2061 | +{ |
---|
| 2062 | + rtt_status_info_t *rtt_status; |
---|
| 2063 | +#ifndef DHD_DUMP_ON_RTT_TIMEOUT |
---|
| 2064 | + rtt_target_info_t *rtt_target = NULL; |
---|
| 2065 | + rtt_target_info_t *rtt_target_info = NULL; |
---|
| 2066 | +#ifdef WL_NAN |
---|
| 2067 | + nan_ranging_inst_t *ranging_inst = NULL; |
---|
| 2068 | + int ret = BCME_OK; |
---|
| 2069 | + uint32 status; |
---|
| 2070 | + struct net_device *ndev = dhd_linux_get_primary_netdev(dhd); |
---|
| 2071 | + struct bcm_cfg80211 *cfg = wiphy_priv(ndev->ieee80211_ptr->wiphy); |
---|
| 2072 | +#endif /* WL_NAN */ |
---|
| 2073 | +#endif /* !DHD_DUMP_ON_RTT_TIMEOUT */ |
---|
| 2074 | + |
---|
| 2075 | + rtt_status = GET_RTTSTATE(dhd); |
---|
| 2076 | + if (!rtt_status) { |
---|
| 2077 | + DHD_RTT_ERR(("Proxd timer expired but no RTT status\n")); |
---|
| 2078 | + goto exit; |
---|
| 2079 | + } |
---|
| 2080 | + |
---|
| 2081 | + if (RTT_IS_STOPPED(rtt_status)) { |
---|
| 2082 | + DHD_RTT_ERR(("Proxd timer expired but no RTT Request\n")); |
---|
| 2083 | + goto exit; |
---|
| 2084 | + } |
---|
| 2085 | + |
---|
| 2086 | +#ifdef DHD_DUMP_ON_RTT_TIMEOUT |
---|
| 2087 | + /* Dump, and Panic depending on memdump.info */ |
---|
| 2088 | + if (dhd_query_bus_erros(dhd)) { |
---|
| 2089 | + goto exit; |
---|
| 2090 | + } |
---|
| 2091 | +#ifdef DHD_FW_COREDUMP |
---|
| 2092 | + if (dhd->memdump_enabled) { |
---|
| 2093 | + /* Behave based on user memdump info */ |
---|
| 2094 | + dhd->memdump_type = DUMP_TYPE_PROXD_TIMEOUT; |
---|
| 2095 | + dhd_bus_mem_dump(dhd); |
---|
| 2096 | + } |
---|
| 2097 | +#endif /* DHD_FW_COREDUMP */ |
---|
| 2098 | +#else /* DHD_DUMP_ON_RTT_TIMEOUT */ |
---|
| 2099 | + /* Cancel RTT for target and proceed to next target */ |
---|
| 2100 | + rtt_target_info = rtt_status->rtt_config.target_info; |
---|
| 2101 | + if ((!rtt_target_info) || |
---|
| 2102 | + (rtt_status->cur_idx >= rtt_status->rtt_config.rtt_target_cnt)) { |
---|
| 2103 | + goto exit; |
---|
| 2104 | + } |
---|
| 2105 | + rtt_target = &rtt_target_info[rtt_status->cur_idx]; |
---|
| 2106 | + WL_ERR(("Proxd timer expired for Target: "MACDBG" \n", MAC2STRDBG(&rtt_target->addr))); |
---|
| 2107 | +#ifdef WL_NAN |
---|
| 2108 | + if (rtt_target->peer == RTT_PEER_NAN) { |
---|
| 2109 | + ranging_inst = wl_cfgnan_check_for_ranging(cfg, &rtt_target->addr); |
---|
| 2110 | + if (!ranging_inst) { |
---|
| 2111 | + goto exit; |
---|
| 2112 | + } |
---|
| 2113 | + ret = wl_cfgnan_cancel_ranging(ndev, cfg, ranging_inst->range_id, |
---|
| 2114 | + NAN_RNG_TERM_FLAG_IMMEDIATE, &status); |
---|
| 2115 | + if (unlikely(ret) || unlikely(status)) { |
---|
| 2116 | + WL_ERR(("%s:nan range cancel failed ret = %d status = %d\n", |
---|
| 2117 | + __FUNCTION__, ret, status)); |
---|
| 2118 | + } |
---|
| 2119 | + } else |
---|
| 2120 | +#endif /* WL_NAN */ |
---|
| 2121 | + { |
---|
| 2122 | + /* For Legacy RTT */ |
---|
| 2123 | + dhd_rtt_delete_session(dhd, FTM_DEFAULT_SESSION); |
---|
| 2124 | + } |
---|
| 2125 | + dhd_rtt_create_failure_result(rtt_status, &rtt_target->addr); |
---|
| 2126 | + dhd_rtt_handle_rtt_session_end(dhd); |
---|
| 2127 | +#endif /* DHD_DUMP_ON_RTT_TIMEOUT */ |
---|
| 2128 | +exit: |
---|
| 2129 | + return; |
---|
| 2130 | +} |
---|
| 2131 | + |
---|
| 2132 | +static void |
---|
| 2133 | +dhd_rtt_timeout_work(struct work_struct *work) |
---|
| 2134 | +{ |
---|
| 2135 | + rtt_status_info_t *rtt_status = NULL; |
---|
| 2136 | + dhd_pub_t *dhd = NULL; |
---|
| 2137 | + |
---|
| 2138 | +#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) |
---|
| 2139 | +#pragma GCC diagnostic push |
---|
| 2140 | +#pragma GCC diagnostic ignored "-Wcast-qual" |
---|
| 2141 | +#endif // endif |
---|
| 2142 | + rtt_status = container_of(work, rtt_status_info_t, proxd_timeout.work); |
---|
| 2143 | +#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) |
---|
| 2144 | +#pragma GCC diagnostic pop |
---|
| 2145 | +#endif // endif |
---|
| 2146 | + |
---|
| 2147 | + dhd = rtt_status->dhd; |
---|
| 2148 | + if (dhd == NULL) { |
---|
| 2149 | + DHD_RTT_ERR(("%s : dhd is NULL\n", __FUNCTION__)); |
---|
| 2150 | + return; |
---|
| 2151 | + } |
---|
| 2152 | + mutex_lock(&rtt_status->rtt_mutex); |
---|
| 2153 | + (void) dhd_rtt_timeout(dhd); |
---|
| 2154 | + mutex_unlock(&rtt_status->rtt_mutex); |
---|
1235 | 2155 | } |
---|
1236 | 2156 | |
---|
1237 | 2157 | static int |
---|
1238 | 2158 | dhd_rtt_start(dhd_pub_t *dhd) |
---|
1239 | 2159 | { |
---|
1240 | 2160 | int err = BCME_OK; |
---|
| 2161 | + int err_at = 0; |
---|
1241 | 2162 | char eabuf[ETHER_ADDR_STR_LEN]; |
---|
1242 | 2163 | char chanbuf[CHANSPEC_STR_LEN]; |
---|
1243 | | - int mpc = 0; |
---|
| 2164 | + int pm = PM_OFF; |
---|
1244 | 2165 | int ftm_cfg_cnt = 0; |
---|
1245 | 2166 | int ftm_param_cnt = 0; |
---|
1246 | 2167 | uint32 rspec = 0; |
---|
.. | .. |
---|
1248 | 2169 | ftm_config_param_info_t ftm_params[FTM_MAX_PARAMS]; |
---|
1249 | 2170 | rtt_target_info_t *rtt_target; |
---|
1250 | 2171 | rtt_status_info_t *rtt_status; |
---|
| 2172 | + struct net_device *dev = dhd_linux_get_primary_netdev(dhd); |
---|
| 2173 | + u8 ioctl_buf[WLC_IOCTL_SMLEN]; |
---|
| 2174 | + u8 rtt_invalid_reason = RTT_STATE_VALID; |
---|
| 2175 | + int rtt_sched_type = RTT_TYPE_INVALID; |
---|
| 2176 | + |
---|
1251 | 2177 | NULL_CHECK(dhd, "dhd is NULL", err); |
---|
1252 | 2178 | |
---|
1253 | 2179 | rtt_status = GET_RTTSTATE(dhd); |
---|
1254 | 2180 | NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
| 2181 | + |
---|
| 2182 | + DHD_RTT(("Enter %s\n", __FUNCTION__)); |
---|
| 2183 | + |
---|
| 2184 | + if (RTT_IS_STOPPED(rtt_status)) { |
---|
| 2185 | + DHD_RTT(("No Directed RTT target to process, check for geofence\n")); |
---|
| 2186 | + goto geofence; |
---|
| 2187 | + } |
---|
| 2188 | + |
---|
1255 | 2189 | if (rtt_status->cur_idx >= rtt_status->rtt_config.rtt_target_cnt) { |
---|
1256 | 2190 | err = BCME_RANGE; |
---|
1257 | | - DHD_ERROR(("%s : idx %d is out of range\n", __FUNCTION__, rtt_status->cur_idx)); |
---|
1258 | | - goto exit; |
---|
1259 | | - } |
---|
1260 | | - if (RTT_IS_STOPPED(rtt_status)) { |
---|
1261 | | - DHD_ERROR(("RTT is stopped\n")); |
---|
1262 | | - goto exit; |
---|
1263 | | - } |
---|
1264 | | - /* turn off mpc in case of non-associted */ |
---|
1265 | | - if (!dhd_is_associated(dhd, NULL, NULL)) { |
---|
1266 | | - err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc, sizeof(mpc), NULL, 0, TRUE); |
---|
1267 | | - if (err) { |
---|
1268 | | - DHD_ERROR(("%s : failed to set mpc\n", __FUNCTION__)); |
---|
1269 | | - goto exit; |
---|
| 2191 | + err_at = 1; |
---|
| 2192 | + DHD_RTT(("%s : idx %d is out of range\n", __FUNCTION__, rtt_status->cur_idx)); |
---|
| 2193 | + if (rtt_status->flags == WL_PROXD_SESSION_FLAG_TARGET) { |
---|
| 2194 | + DHD_RTT_ERR(("STA is set as Target/Responder \n")); |
---|
| 2195 | + err = BCME_ERROR; |
---|
| 2196 | + err_at = 1; |
---|
1270 | 2197 | } |
---|
1271 | | - rtt_status->mpc = 1; /* Either failure or complete, we need to enable mpc */ |
---|
| 2198 | + goto exit; |
---|
| 2199 | + } |
---|
| 2200 | + |
---|
| 2201 | + rtt_status->pm = PM_OFF; |
---|
| 2202 | + err = wldev_ioctl_get(dev, WLC_GET_PM, &rtt_status->pm, sizeof(rtt_status->pm)); |
---|
| 2203 | + if (err) { |
---|
| 2204 | + DHD_RTT_ERR(("Failed to get the PM value\n")); |
---|
| 2205 | + } else { |
---|
| 2206 | + err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm)); |
---|
| 2207 | + if (err) { |
---|
| 2208 | + DHD_RTT_ERR(("Failed to set the PM\n")); |
---|
| 2209 | + rtt_status->pm_restore = FALSE; |
---|
| 2210 | + } else { |
---|
| 2211 | + rtt_status->pm_restore = TRUE; |
---|
| 2212 | + } |
---|
1272 | 2213 | } |
---|
1273 | 2214 | |
---|
1274 | 2215 | mutex_lock(&rtt_status->rtt_mutex); |
---|
1275 | 2216 | /* Get a target information */ |
---|
1276 | 2217 | rtt_target = &rtt_status->rtt_config.target_info[rtt_status->cur_idx]; |
---|
1277 | 2218 | mutex_unlock(&rtt_status->rtt_mutex); |
---|
1278 | | - DHD_ERROR(("%s enter\n", __FUNCTION__)); |
---|
| 2219 | + DHD_RTT(("%s enter\n", __FUNCTION__)); |
---|
| 2220 | + |
---|
| 2221 | + if (ETHER_ISNULLADDR(rtt_target->addr.octet)) { |
---|
| 2222 | + err = BCME_BADADDR; |
---|
| 2223 | + err_at = 2; |
---|
| 2224 | + DHD_RTT(("RTT Target addr is NULL\n")); |
---|
| 2225 | + goto exit; |
---|
| 2226 | + } |
---|
| 2227 | + |
---|
| 2228 | + /* check for dp/others concurrency */ |
---|
| 2229 | + rtt_invalid_reason = dhd_rtt_invalid_states(dev, &rtt_target->addr); |
---|
| 2230 | + if (rtt_invalid_reason != RTT_STATE_VALID) { |
---|
| 2231 | + err = BCME_BUSY; |
---|
| 2232 | + err_at = 3; |
---|
| 2233 | + DHD_RTT(("DRV State is not valid for RTT\n")); |
---|
| 2234 | + goto exit; |
---|
| 2235 | + } |
---|
| 2236 | + |
---|
| 2237 | +#ifdef WL_NAN |
---|
| 2238 | + if (rtt_target->peer == RTT_PEER_NAN) { |
---|
| 2239 | + rtt_sched_type = RTT_TYPE_NAN_DIRECTED; |
---|
| 2240 | + rtt_status->status = RTT_ENABLED; |
---|
| 2241 | + /* Ignore return value..failure taken care inside the API */ |
---|
| 2242 | + dhd_rtt_nan_start_session(dhd, rtt_target); |
---|
| 2243 | + goto exit; |
---|
| 2244 | + } |
---|
| 2245 | +#endif /* WL_NAN */ |
---|
1279 | 2246 | if (!RTT_IS_ENABLED(rtt_status)) { |
---|
1280 | 2247 | /* enable ftm */ |
---|
1281 | 2248 | err = dhd_rtt_ftm_enable(dhd, TRUE); |
---|
1282 | 2249 | if (err) { |
---|
1283 | | - DHD_ERROR(("failed to enable FTM (%d)\n", err)); |
---|
| 2250 | + DHD_RTT_ERR(("failed to enable FTM (%d)\n", err)); |
---|
| 2251 | + err_at = 5; |
---|
1284 | 2252 | goto exit; |
---|
1285 | 2253 | } |
---|
1286 | 2254 | } |
---|
.. | .. |
---|
1288 | 2256 | /* delete session of index default sesession */ |
---|
1289 | 2257 | err = dhd_rtt_delete_session(dhd, FTM_DEFAULT_SESSION); |
---|
1290 | 2258 | if (err < 0 && err != BCME_NOTFOUND) { |
---|
1291 | | - DHD_ERROR(("failed to delete session of FTM (%d)\n", err)); |
---|
| 2259 | + DHD_RTT_ERR(("failed to delete session of FTM (%d)\n", err)); |
---|
| 2260 | + err_at = 6; |
---|
1292 | 2261 | goto exit; |
---|
1293 | 2262 | } |
---|
1294 | 2263 | rtt_status->status = RTT_ENABLED; |
---|
.. | .. |
---|
1300 | 2269 | ftm_configs[ftm_cfg_cnt++].flags = WL_PROXD_SESSION_FLAG_INITIATOR; |
---|
1301 | 2270 | dhd_rtt_ftm_config(dhd, FTM_DEFAULT_SESSION, FTM_CONFIG_CAT_OPTIONS, |
---|
1302 | 2271 | ftm_configs, ftm_cfg_cnt); |
---|
| 2272 | + |
---|
| 2273 | + memset(ioctl_buf, 0, WLC_IOCTL_SMLEN); |
---|
| 2274 | + |
---|
| 2275 | + /* Rand Mac for newer version in place of cur_eth */ |
---|
| 2276 | + if (dhd->wlc_ver_major < RTT_IOV_CUR_ETH_OBSOLETE) { |
---|
| 2277 | + err = wldev_iovar_getbuf(dev, "cur_etheraddr", NULL, 0, |
---|
| 2278 | + ioctl_buf, WLC_IOCTL_SMLEN, NULL); |
---|
| 2279 | + if (err) { |
---|
| 2280 | + DHD_RTT_ERR(("WLC_GET_CUR_ETHERADDR failed, error %d\n", err)); |
---|
| 2281 | + err_at = 7; |
---|
| 2282 | + goto exit; |
---|
| 2283 | + } |
---|
| 2284 | + memcpy(rtt_target->local_addr.octet, ioctl_buf, ETHER_ADDR_LEN); |
---|
| 2285 | + |
---|
| 2286 | + /* local mac address */ |
---|
| 2287 | + if (!ETHER_ISNULLADDR(rtt_target->local_addr.octet)) { |
---|
| 2288 | + ftm_params[ftm_param_cnt].mac_addr = rtt_target->local_addr; |
---|
| 2289 | + ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_CUR_ETHER_ADDR; |
---|
| 2290 | + bcm_ether_ntoa(&rtt_target->local_addr, eabuf); |
---|
| 2291 | + DHD_RTT((">\t local %s\n", eabuf)); |
---|
| 2292 | + } |
---|
| 2293 | + } |
---|
1303 | 2294 | /* target's mac address */ |
---|
1304 | 2295 | if (!ETHER_ISNULLADDR(rtt_target->addr.octet)) { |
---|
1305 | 2296 | ftm_params[ftm_param_cnt].mac_addr = rtt_target->addr; |
---|
1306 | 2297 | ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_PEER_MAC; |
---|
1307 | | - DHD_ERROR((">\t target %s\n", bcm_ether_ntoa(&rtt_target->addr, eabuf))); |
---|
| 2298 | + bcm_ether_ntoa(&rtt_target->addr, eabuf); |
---|
| 2299 | + DHD_RTT((">\t target %s\n", eabuf)); |
---|
1308 | 2300 | } |
---|
1309 | 2301 | /* target's chanspec */ |
---|
1310 | 2302 | if (rtt_target->chanspec) { |
---|
1311 | 2303 | ftm_params[ftm_param_cnt].chanspec = htol32((uint32)rtt_target->chanspec); |
---|
1312 | 2304 | ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_CHANSPEC; |
---|
1313 | | - DHD_ERROR((">\t chanspec : %s\n", wf_chspec_ntoa(rtt_target->chanspec, chanbuf))); |
---|
| 2305 | + wf_chspec_ntoa(rtt_target->chanspec, chanbuf); |
---|
| 2306 | + DHD_RTT((">\t chanspec : %s\n", chanbuf)); |
---|
1314 | 2307 | } |
---|
1315 | 2308 | /* num-burst */ |
---|
1316 | 2309 | if (rtt_target->num_burst) { |
---|
1317 | 2310 | ftm_params[ftm_param_cnt].data16 = htol16(rtt_target->num_burst); |
---|
1318 | 2311 | ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_NUM_BURST; |
---|
1319 | | - DHD_ERROR((">\t num of burst : %d\n", rtt_target->num_burst)); |
---|
| 2312 | + DHD_RTT((">\t num of burst : %d\n", rtt_target->num_burst)); |
---|
1320 | 2313 | } |
---|
1321 | 2314 | /* number of frame per burst */ |
---|
1322 | | - if (rtt_target->num_frames_per_burst == 0) { |
---|
1323 | | - rtt_target->num_frames_per_burst = |
---|
1324 | | - CHSPEC_IS20(rtt_target->chanspec) ? FTM_DEFAULT_CNT_20M : |
---|
1325 | | - CHSPEC_IS40(rtt_target->chanspec) ? FTM_DEFAULT_CNT_40M : |
---|
1326 | | - FTM_DEFAULT_CNT_80M; |
---|
| 2315 | + rtt_target->num_frames_per_burst = FTM_DEFAULT_CNT_80M; |
---|
| 2316 | + if (CHSPEC_IS80(rtt_target->chanspec)) { |
---|
| 2317 | + rtt_target->num_frames_per_burst = FTM_DEFAULT_CNT_80M; |
---|
| 2318 | + } else if (CHSPEC_IS40(rtt_target->chanspec)) { |
---|
| 2319 | + rtt_target->num_frames_per_burst = FTM_DEFAULT_CNT_40M; |
---|
| 2320 | + } else if (CHSPEC_IS20(rtt_target->chanspec)) { |
---|
| 2321 | + rtt_target->num_frames_per_burst = FTM_DEFAULT_CNT_20M; |
---|
1327 | 2322 | } |
---|
1328 | 2323 | ftm_params[ftm_param_cnt].data16 = htol16(rtt_target->num_frames_per_burst); |
---|
1329 | 2324 | ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_BURST_NUM_FTM; |
---|
1330 | | - DHD_ERROR((">\t number of frame per burst : %d\n", rtt_target->num_frames_per_burst)); |
---|
| 2325 | + DHD_RTT((">\t number of frame per burst : %d\n", rtt_target->num_frames_per_burst)); |
---|
| 2326 | + |
---|
1331 | 2327 | /* FTM retry count */ |
---|
1332 | 2328 | if (rtt_target->num_retries_per_ftm) { |
---|
1333 | 2329 | ftm_params[ftm_param_cnt].data8 = rtt_target->num_retries_per_ftm; |
---|
1334 | 2330 | ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_FTM_RETRIES; |
---|
1335 | | - DHD_ERROR((">\t retry count of FTM : %d\n", rtt_target->num_retries_per_ftm)); |
---|
| 2331 | + DHD_RTT((">\t retry count of FTM : %d\n", rtt_target->num_retries_per_ftm)); |
---|
1336 | 2332 | } |
---|
1337 | 2333 | /* FTM Request retry count */ |
---|
1338 | 2334 | if (rtt_target->num_retries_per_ftmr) { |
---|
1339 | 2335 | ftm_params[ftm_param_cnt].data8 = rtt_target->num_retries_per_ftmr; |
---|
1340 | 2336 | ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_FTM_REQ_RETRIES; |
---|
1341 | | - DHD_ERROR((">\t retry count of FTM Req : %d\n", rtt_target->num_retries_per_ftm)); |
---|
| 2337 | + DHD_RTT((">\t retry count of FTM Req : %d\n", rtt_target->num_retries_per_ftmr)); |
---|
1342 | 2338 | } |
---|
1343 | 2339 | /* burst-period */ |
---|
1344 | 2340 | if (rtt_target->burst_period) { |
---|
.. | .. |
---|
1346 | 2342 | htol32(rtt_target->burst_period); /* ms */ |
---|
1347 | 2343 | ftm_params[ftm_param_cnt].data_intvl.tmu = WL_PROXD_TMU_MILLI_SEC; |
---|
1348 | 2344 | ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_BURST_PERIOD; |
---|
1349 | | - DHD_ERROR((">\t burst period : %d ms\n", rtt_target->burst_period)); |
---|
| 2345 | + DHD_RTT((">\t burst period : %d ms\n", rtt_target->burst_period)); |
---|
1350 | 2346 | } |
---|
| 2347 | + /* Setting both duration and timeout to MAX duration |
---|
| 2348 | + * to handle the congestion environments. |
---|
| 2349 | + * Hence ignoring the user config. |
---|
| 2350 | + */ |
---|
1351 | 2351 | /* burst-duration */ |
---|
| 2352 | + rtt_target->burst_duration = FTM_MAX_BURST_DUR_TMO_MS; |
---|
1352 | 2353 | if (rtt_target->burst_duration) { |
---|
1353 | 2354 | ftm_params[ftm_param_cnt].data_intvl.intvl = |
---|
1354 | | - htol32(rtt_target->burst_period); /* ms */ |
---|
| 2355 | + htol32(rtt_target->burst_duration); /* ms */ |
---|
1355 | 2356 | ftm_params[ftm_param_cnt].data_intvl.tmu = WL_PROXD_TMU_MILLI_SEC; |
---|
1356 | 2357 | ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_BURST_DURATION; |
---|
1357 | | - DHD_ERROR((">\t burst duration : %d ms\n", |
---|
| 2358 | + DHD_RTT((">\t burst duration : %d ms\n", |
---|
1358 | 2359 | rtt_target->burst_duration)); |
---|
1359 | 2360 | } |
---|
| 2361 | + /* burst-timeout */ |
---|
| 2362 | + rtt_target->burst_timeout = FTM_MAX_BURST_DUR_TMO_MS; |
---|
| 2363 | + if (rtt_target->burst_timeout) { |
---|
| 2364 | + ftm_params[ftm_param_cnt].data_intvl.intvl = |
---|
| 2365 | + htol32(rtt_target->burst_timeout); /* ms */ |
---|
| 2366 | + ftm_params[ftm_param_cnt].data_intvl.tmu = WL_PROXD_TMU_MILLI_SEC; |
---|
| 2367 | + ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_BURST_TIMEOUT; |
---|
| 2368 | + DHD_RTT((">\t burst timeout : %d ms\n", |
---|
| 2369 | + rtt_target->burst_timeout)); |
---|
| 2370 | + } |
---|
| 2371 | + /* event_mask..applicable for only Legacy RTT. |
---|
| 2372 | + * For nan-rtt config happens from firmware |
---|
| 2373 | + */ |
---|
| 2374 | + ftm_params[ftm_param_cnt].event_mask = ((1 << WL_PROXD_EVENT_BURST_END) | |
---|
| 2375 | + (1 << WL_PROXD_EVENT_SESSION_END)); |
---|
| 2376 | + ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_EVENT_MASK; |
---|
| 2377 | + |
---|
1360 | 2378 | if (rtt_target->bw && rtt_target->preamble) { |
---|
1361 | 2379 | bool use_default = FALSE; |
---|
1362 | 2380 | int nss; |
---|
1363 | 2381 | int mcs; |
---|
1364 | 2382 | switch (rtt_target->preamble) { |
---|
1365 | | - case RTT_PREAMBLE_LEGACY: |
---|
1366 | | - rspec |= WL_RSPEC_ENCODE_RATE; /* 11abg */ |
---|
1367 | | - rspec |= WL_RATE_6M; |
---|
1368 | | - break; |
---|
1369 | | - case RTT_PREAMBLE_HT: |
---|
1370 | | - rspec |= WL_RSPEC_ENCODE_HT; /* 11n HT */ |
---|
1371 | | - mcs = 0; /* default MCS 0 */ |
---|
1372 | | - rspec |= mcs; |
---|
1373 | | - break; |
---|
1374 | | - case RTT_PREAMBLE_VHT: |
---|
1375 | | - rspec |= WL_RSPEC_ENCODE_VHT; /* 11ac VHT */ |
---|
1376 | | - mcs = 0; /* default MCS 0 */ |
---|
1377 | | - nss = 1; /* default Nss = 1 */ |
---|
1378 | | - rspec |= (nss << WL_RSPEC_VHT_NSS_SHIFT) | mcs; |
---|
1379 | | - break; |
---|
1380 | | - default: |
---|
1381 | | - DHD_ERROR(("doesn't support this preamble : %d\n", rtt_target->preamble)); |
---|
1382 | | - use_default = TRUE; |
---|
1383 | | - break; |
---|
| 2383 | + case RTT_PREAMBLE_LEGACY: |
---|
| 2384 | + rspec |= WL_RSPEC_ENCODE_RATE; /* 11abg */ |
---|
| 2385 | + rspec |= WL_RATE_6M; |
---|
| 2386 | + break; |
---|
| 2387 | + case RTT_PREAMBLE_HT: |
---|
| 2388 | + rspec |= WL_RSPEC_ENCODE_HT; /* 11n HT */ |
---|
| 2389 | + mcs = 0; /* default MCS 0 */ |
---|
| 2390 | + rspec |= mcs; |
---|
| 2391 | + break; |
---|
| 2392 | + case RTT_PREAMBLE_VHT: |
---|
| 2393 | + rspec |= WL_RSPEC_ENCODE_VHT; /* 11ac VHT */ |
---|
| 2394 | + mcs = 0; /* default MCS 0 */ |
---|
| 2395 | + nss = 1; /* default Nss = 1 */ |
---|
| 2396 | + rspec |= (nss << WL_RSPEC_VHT_NSS_SHIFT) | mcs; |
---|
| 2397 | + break; |
---|
| 2398 | + default: |
---|
| 2399 | + DHD_RTT(("doesn't support this preamble : %d\n", |
---|
| 2400 | + rtt_target->preamble)); |
---|
| 2401 | + use_default = TRUE; |
---|
| 2402 | + break; |
---|
1384 | 2403 | } |
---|
1385 | 2404 | switch (rtt_target->bw) { |
---|
1386 | | - case RTT_BW_20: |
---|
1387 | | - rspec |= WL_RSPEC_BW_20MHZ; |
---|
1388 | | - break; |
---|
1389 | | - case RTT_BW_40: |
---|
1390 | | - rspec |= WL_RSPEC_BW_40MHZ; |
---|
1391 | | - break; |
---|
1392 | | - case RTT_BW_80: |
---|
1393 | | - rspec |= WL_RSPEC_BW_80MHZ; |
---|
1394 | | - break; |
---|
1395 | | - default: |
---|
1396 | | - DHD_ERROR(("doesn't support this BW : %d\n", rtt_target->bw)); |
---|
1397 | | - use_default = TRUE; |
---|
1398 | | - break; |
---|
| 2405 | + case RTT_BW_20: |
---|
| 2406 | + rspec |= WL_RSPEC_BW_20MHZ; |
---|
| 2407 | + break; |
---|
| 2408 | + case RTT_BW_40: |
---|
| 2409 | + rspec |= WL_RSPEC_BW_40MHZ; |
---|
| 2410 | + break; |
---|
| 2411 | + case RTT_BW_80: |
---|
| 2412 | + rspec |= WL_RSPEC_BW_80MHZ; |
---|
| 2413 | + break; |
---|
| 2414 | + default: |
---|
| 2415 | + DHD_RTT(("doesn't support this BW : %d\n", rtt_target->bw)); |
---|
| 2416 | + use_default = TRUE; |
---|
| 2417 | + break; |
---|
1399 | 2418 | } |
---|
1400 | 2419 | if (!use_default) { |
---|
1401 | 2420 | ftm_params[ftm_param_cnt].data32 = htol32(rspec); |
---|
1402 | 2421 | ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_RATESPEC; |
---|
1403 | | - DHD_ERROR((">\t ratespec : %d\n", rspec)); |
---|
| 2422 | + DHD_RTT((">\t ratespec : %d\n", rspec)); |
---|
1404 | 2423 | } |
---|
1405 | 2424 | |
---|
1406 | 2425 | } |
---|
| 2426 | + dhd_set_rand_mac_oui(dhd); |
---|
1407 | 2427 | dhd_rtt_ftm_config(dhd, FTM_DEFAULT_SESSION, FTM_CONFIG_CAT_GENERAL, |
---|
1408 | | - ftm_params, ftm_param_cnt); |
---|
| 2428 | + ftm_params, ftm_param_cnt); |
---|
1409 | 2429 | |
---|
| 2430 | + rtt_sched_type = RTT_TYPE_LEGACY; |
---|
1410 | 2431 | err = dhd_rtt_start_session(dhd, FTM_DEFAULT_SESSION, TRUE); |
---|
1411 | 2432 | if (err) { |
---|
1412 | | - DHD_ERROR(("failed to start session of FTM : error %d\n", err)); |
---|
| 2433 | + DHD_RTT_ERR(("failed to start session of FTM : error %d\n", err)); |
---|
| 2434 | + err_at = 8; |
---|
| 2435 | + } else { |
---|
| 2436 | + /* schedule proxd timeout */ |
---|
| 2437 | + schedule_delayed_work(&rtt_status->proxd_timeout, |
---|
| 2438 | + msecs_to_jiffies(DHD_NAN_RTT_TIMER_INTERVAL_MS)); |
---|
| 2439 | + |
---|
1413 | 2440 | } |
---|
| 2441 | + |
---|
| 2442 | + goto exit; |
---|
| 2443 | +geofence: |
---|
| 2444 | +#ifdef WL_NAN |
---|
| 2445 | + /* sched geofencing rtt */ |
---|
| 2446 | + rtt_sched_type = RTT_TYPE_NAN_GEOFENCE; |
---|
| 2447 | + if ((err = dhd_rtt_sched_geofencing_target(dhd)) != BCME_OK) { |
---|
| 2448 | + DHD_RTT_ERR(("geofencing sched failed, err = %d\n", err)); |
---|
| 2449 | + err_at = 9; |
---|
| 2450 | + } |
---|
| 2451 | +#endif /* WL_NAN */ |
---|
| 2452 | + |
---|
1414 | 2453 | exit: |
---|
1415 | 2454 | if (err) { |
---|
| 2455 | + /* RTT Failed */ |
---|
| 2456 | + DHD_RTT_ERR(("dhd_rtt_start: Failed & RTT_STOPPED, err = %d," |
---|
| 2457 | + " err_at = %d, rtt_sched_type = %d, rtt_invalid_reason = %d\n" |
---|
| 2458 | + " sched_reason = %d", |
---|
| 2459 | + err, err_at, rtt_sched_type, rtt_invalid_reason, |
---|
| 2460 | + rtt_status->rtt_sched_reason)); |
---|
1416 | 2461 | rtt_status->status = RTT_STOPPED; |
---|
1417 | 2462 | /* disable FTM */ |
---|
1418 | 2463 | dhd_rtt_ftm_enable(dhd, FALSE); |
---|
1419 | | - if (rtt_status->mpc) { |
---|
1420 | | - /* enable mpc again in case of error */ |
---|
1421 | | - mpc = 1; |
---|
1422 | | - rtt_status->mpc = 0; |
---|
1423 | | - err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc, sizeof(mpc), |
---|
1424 | | - NULL, 0, TRUE); |
---|
| 2464 | + if (rtt_status->pm_restore) { |
---|
| 2465 | + pm = PM_FAST; |
---|
| 2466 | + DHD_RTT_ERR(("pm_restore =%d func =%s \n", |
---|
| 2467 | + rtt_status->pm_restore, __FUNCTION__)); |
---|
| 2468 | + err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm)); |
---|
| 2469 | + if (err) { |
---|
| 2470 | + DHD_RTT_ERR(("Failed to set PM \n")); |
---|
| 2471 | + } else { |
---|
| 2472 | + rtt_status->pm_restore = FALSE; |
---|
| 2473 | + } |
---|
1425 | 2474 | } |
---|
1426 | 2475 | } |
---|
1427 | 2476 | return err; |
---|
1428 | 2477 | } |
---|
| 2478 | +#endif /* WL_CFG80211 */ |
---|
1429 | 2479 | |
---|
1430 | 2480 | int |
---|
1431 | 2481 | dhd_rtt_register_noti_callback(dhd_pub_t *dhd, void *ctx, dhd_rtt_compl_noti_fn noti_fn) |
---|
.. | .. |
---|
1439 | 2489 | rtt_status = GET_RTTSTATE(dhd); |
---|
1440 | 2490 | NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
1441 | 2491 | spin_lock_bh(¬i_list_lock); |
---|
| 2492 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
1442 | 2493 | list_for_each_entry(iter, &rtt_status->noti_fn_list, list) { |
---|
| 2494 | + GCC_DIAGNOSTIC_POP(); |
---|
1443 | 2495 | if (iter->noti_fn == noti_fn) { |
---|
1444 | 2496 | goto exit; |
---|
1445 | 2497 | } |
---|
.. | .. |
---|
1468 | 2520 | rtt_status = GET_RTTSTATE(dhd); |
---|
1469 | 2521 | NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
1470 | 2522 | spin_lock_bh(¬i_list_lock); |
---|
| 2523 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
1471 | 2524 | list_for_each_entry(iter, &rtt_status->noti_fn_list, list) { |
---|
| 2525 | + GCC_DIAGNOSTIC_POP(); |
---|
1472 | 2526 | if (iter->noti_fn == noti_fn) { |
---|
1473 | 2527 | cb = iter; |
---|
1474 | 2528 | list_del(&cb->list); |
---|
1475 | 2529 | break; |
---|
1476 | 2530 | } |
---|
1477 | 2531 | } |
---|
| 2532 | + |
---|
1478 | 2533 | spin_unlock_bh(¬i_list_lock); |
---|
1479 | 2534 | if (cb) { |
---|
1480 | 2535 | kfree(cb); |
---|
.. | .. |
---|
1486 | 2541 | dhd_rtt_convert_rate_to_host(uint32 rspec) |
---|
1487 | 2542 | { |
---|
1488 | 2543 | wifi_rate_t host_rate; |
---|
| 2544 | + uint32 bandwidth; |
---|
1489 | 2545 | memset(&host_rate, 0, sizeof(wifi_rate_t)); |
---|
1490 | | - if ((rspec & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_RATE) { |
---|
| 2546 | + if (RSPEC_ISLEGACY(rspec)) { |
---|
1491 | 2547 | host_rate.preamble = 0; |
---|
1492 | | - } else if ((rspec & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_HT) { |
---|
| 2548 | + } else if (RSPEC_ISHT(rspec)) { |
---|
1493 | 2549 | host_rate.preamble = 2; |
---|
1494 | 2550 | host_rate.rateMcsIdx = rspec & WL_RSPEC_RATE_MASK; |
---|
1495 | | - } else if ((rspec & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_VHT) { |
---|
| 2551 | + } else if (RSPEC_ISVHT(rspec)) { |
---|
1496 | 2552 | host_rate.preamble = 3; |
---|
1497 | 2553 | host_rate.rateMcsIdx = rspec & WL_RSPEC_VHT_MCS_MASK; |
---|
1498 | 2554 | host_rate.nss = (rspec & WL_RSPEC_VHT_NSS_MASK) >> WL_RSPEC_VHT_NSS_SHIFT; |
---|
1499 | 2555 | } |
---|
1500 | | - host_rate.bw = (rspec & WL_RSPEC_BW_MASK) - 1; |
---|
| 2556 | + |
---|
| 2557 | + bandwidth = RSPEC_BW(rspec); |
---|
| 2558 | + switch (bandwidth) { |
---|
| 2559 | + case WL_RSPEC_BW_20MHZ: |
---|
| 2560 | + host_rate.bw = RTT_RATE_20M; |
---|
| 2561 | + break; |
---|
| 2562 | + case WL_RSPEC_BW_40MHZ: |
---|
| 2563 | + host_rate.bw = RTT_RATE_40M; |
---|
| 2564 | + break; |
---|
| 2565 | + case WL_RSPEC_BW_80MHZ: |
---|
| 2566 | + host_rate.bw = RTT_RATE_80M; |
---|
| 2567 | + break; |
---|
| 2568 | + case WL_RSPEC_BW_160MHZ: |
---|
| 2569 | + host_rate.bw = RTT_RATE_160M; |
---|
| 2570 | + break; |
---|
| 2571 | + default: |
---|
| 2572 | + host_rate.bw = RTT_RATE_20M; |
---|
| 2573 | + break; |
---|
| 2574 | + } |
---|
| 2575 | + |
---|
1501 | 2576 | host_rate.bitrate = rate_rspec2rate(rspec) / 100; /* 100kbps */ |
---|
1502 | 2577 | DHD_RTT(("bit rate : %d\n", host_rate.bitrate)); |
---|
1503 | 2578 | return host_rate; |
---|
1504 | 2579 | } |
---|
1505 | 2580 | |
---|
1506 | | - |
---|
| 2581 | +#define FTM_FRAME_TYPES {"SETUP", "TRIGGER", "TIMESTAMP"} |
---|
1507 | 2582 | static int |
---|
1508 | | -dhd_rtt_convert_results_to_host(rtt_report_t *rtt_report, uint8 *p_data, uint16 tlvid, uint16 len) |
---|
| 2583 | +dhd_rtt_convert_results_to_host_v1(rtt_result_t *rtt_result, const uint8 *p_data, |
---|
| 2584 | + uint16 tlvid, uint16 len) |
---|
1509 | 2585 | { |
---|
| 2586 | + int i; |
---|
1510 | 2587 | int err = BCME_OK; |
---|
1511 | 2588 | char eabuf[ETHER_ADDR_STR_LEN]; |
---|
1512 | | - wl_proxd_rtt_result_t *p_data_info; |
---|
1513 | 2589 | wl_proxd_result_flags_t flags; |
---|
1514 | 2590 | wl_proxd_session_state_t session_state; |
---|
1515 | 2591 | wl_proxd_status_t proxd_status; |
---|
1516 | 2592 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) |
---|
1517 | 2593 | struct timespec64 ts; |
---|
1518 | | -#else |
---|
| 2594 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) |
---|
1519 | 2595 | struct timespec ts; |
---|
1520 | | -#endif |
---|
| 2596 | +#endif /* LINUX_VER >= 2.6.39 */ |
---|
1521 | 2597 | uint32 ratespec; |
---|
1522 | 2598 | uint32 avg_dist; |
---|
1523 | | - wl_proxd_rtt_sample_t *p_sample; |
---|
| 2599 | + const wl_proxd_rtt_result_v1_t *p_data_info = NULL; |
---|
| 2600 | + const wl_proxd_rtt_sample_v1_t *p_sample_avg = NULL; |
---|
| 2601 | + const wl_proxd_rtt_sample_v1_t *p_sample = NULL; |
---|
1524 | 2602 | wl_proxd_intvl_t rtt; |
---|
1525 | 2603 | wl_proxd_intvl_t p_time; |
---|
| 2604 | + uint16 num_rtt = 0, snr = 0, bitflips = 0; |
---|
| 2605 | + wl_proxd_phy_error_t tof_phy_error = 0; |
---|
| 2606 | + wl_proxd_phy_error_t tof_phy_tgt_error = 0; |
---|
| 2607 | + wl_proxd_snr_t tof_target_snr = 0; |
---|
| 2608 | + wl_proxd_bitflips_t tof_target_bitflips = 0; |
---|
| 2609 | + int16 rssi = 0; |
---|
| 2610 | + int32 dist = 0; |
---|
| 2611 | + uint8 num_ftm = 0; |
---|
| 2612 | + char *ftm_frame_types[] = FTM_FRAME_TYPES; |
---|
| 2613 | + rtt_report_t *rtt_report = &(rtt_result->report); |
---|
| 2614 | + |
---|
| 2615 | + BCM_REFERENCE(ftm_frame_types); |
---|
| 2616 | + BCM_REFERENCE(dist); |
---|
| 2617 | + BCM_REFERENCE(rssi); |
---|
| 2618 | + BCM_REFERENCE(tof_target_bitflips); |
---|
| 2619 | + BCM_REFERENCE(tof_target_snr); |
---|
| 2620 | + BCM_REFERENCE(tof_phy_tgt_error); |
---|
| 2621 | + BCM_REFERENCE(tof_phy_error); |
---|
| 2622 | + BCM_REFERENCE(bitflips); |
---|
| 2623 | + BCM_REFERENCE(snr); |
---|
| 2624 | + BCM_REFERENCE(session_state); |
---|
| 2625 | + BCM_REFERENCE(ftm_session_state_value_to_logstr); |
---|
1526 | 2626 | |
---|
1527 | 2627 | NULL_CHECK(rtt_report, "rtt_report is NULL", err); |
---|
1528 | 2628 | NULL_CHECK(p_data, "p_data is NULL", err); |
---|
1529 | 2629 | DHD_RTT(("%s enter\n", __FUNCTION__)); |
---|
1530 | | - p_data_info = (wl_proxd_rtt_result_t *) p_data; |
---|
| 2630 | + p_data_info = (const wl_proxd_rtt_result_v1_t *) p_data; |
---|
1531 | 2631 | /* unpack and format 'flags' for display */ |
---|
1532 | 2632 | flags = ltoh16_ua(&p_data_info->flags); |
---|
1533 | 2633 | |
---|
1534 | 2634 | /* session state and status */ |
---|
1535 | 2635 | session_state = ltoh16_ua(&p_data_info->state); |
---|
1536 | 2636 | proxd_status = ltoh32_ua(&p_data_info->status); |
---|
| 2637 | + bcm_ether_ntoa((&(p_data_info->peer)), eabuf); |
---|
| 2638 | + ftm_status_value_to_logstr(proxd_status); |
---|
1537 | 2639 | DHD_RTT((">\tTarget(%s) session state=%d(%s), status=%d(%s)\n", |
---|
1538 | | - bcm_ether_ntoa((&(p_data_info->peer)), eabuf), |
---|
| 2640 | + eabuf, |
---|
1539 | 2641 | session_state, |
---|
1540 | 2642 | ftm_session_state_value_to_logstr(session_state), |
---|
1541 | 2643 | proxd_status, |
---|
.. | .. |
---|
1558 | 2660 | p_data_info->num_ftm)); /* in a session */ |
---|
1559 | 2661 | } |
---|
1560 | 2662 | /* show 'avg_rtt' sample */ |
---|
1561 | | - p_sample = &p_data_info->avg_rtt; |
---|
| 2663 | + p_sample_avg = &p_data_info->avg_rtt; |
---|
| 2664 | + ftm_tmu_value_to_logstr(ltoh16_ua(&p_sample_avg->rtt.tmu)); |
---|
1562 | 2665 | DHD_RTT((">\tavg_rtt sample: rssi=%d rtt=%d%s std_deviation =%d.%d ratespec=0x%08x\n", |
---|
1563 | | - (int16) ltoh16_ua(&p_sample->rssi), |
---|
1564 | | - ltoh32_ua(&p_sample->rtt.intvl), |
---|
1565 | | - ftm_tmu_value_to_logstr(ltoh16_ua(&p_sample->rtt.tmu)), |
---|
| 2666 | + (int16) ltoh16_ua(&p_sample_avg->rssi), |
---|
| 2667 | + ltoh32_ua(&p_sample_avg->rtt.intvl), |
---|
| 2668 | + ftm_tmu_value_to_logstr(ltoh16_ua(&p_sample_avg->rtt.tmu)), |
---|
1566 | 2669 | ltoh16_ua(&p_data_info->sd_rtt)/10, ltoh16_ua(&p_data_info->sd_rtt)%10, |
---|
1567 | | - ltoh32_ua(&p_sample->ratespec))); |
---|
| 2670 | + ltoh32_ua(&p_sample_avg->ratespec))); |
---|
1568 | 2671 | |
---|
1569 | 2672 | /* set peer address */ |
---|
1570 | 2673 | rtt_report->addr = p_data_info->peer; |
---|
.. | .. |
---|
1578 | 2681 | /* status */ |
---|
1579 | 2682 | rtt_report->status = ftm_get_statusmap_info(proxd_status, |
---|
1580 | 2683 | &ftm_status_map_info[0], ARRAYSIZE(ftm_status_map_info)); |
---|
| 2684 | + |
---|
1581 | 2685 | /* rssi (0.5db) */ |
---|
1582 | | - rtt_report->rssi = (int16)ltoh16_ua(&p_data_info->avg_rtt.rssi) * 2; |
---|
| 2686 | + rtt_report->rssi = ABS((wl_proxd_rssi_t)ltoh16_ua(&p_data_info->avg_rtt.rssi)) * 2; |
---|
| 2687 | + |
---|
1583 | 2688 | /* rx rate */ |
---|
1584 | 2689 | ratespec = ltoh32_ua(&p_data_info->avg_rtt.ratespec); |
---|
1585 | 2690 | rtt_report->rx_rate = dhd_rtt_convert_rate_to_host(ratespec); |
---|
.. | .. |
---|
1592 | 2697 | /* rtt_sd */ |
---|
1593 | 2698 | rtt.tmu = ltoh16_ua(&p_data_info->avg_rtt.rtt.tmu); |
---|
1594 | 2699 | rtt.intvl = ltoh32_ua(&p_data_info->avg_rtt.rtt.intvl); |
---|
1595 | | - rtt_report->rtt = FTM_INTVL2NSEC(&rtt) * 10; /* nano -> 0.1 nano */ |
---|
| 2700 | + rtt_report->rtt = (wifi_timespan)FTM_INTVL2NSEC(&rtt) * 1000; /* nano -> pico seconds */ |
---|
1596 | 2701 | rtt_report->rtt_sd = ltoh16_ua(&p_data_info->sd_rtt); /* nano -> 0.1 nano */ |
---|
1597 | 2702 | DHD_RTT(("rtt_report->rtt : %llu\n", rtt_report->rtt)); |
---|
1598 | 2703 | DHD_RTT(("rtt_report->rssi : %d (0.5db)\n", rtt_report->rssi)); |
---|
1599 | 2704 | |
---|
1600 | 2705 | /* average distance */ |
---|
1601 | 2706 | if (avg_dist != FTM_INVALID) { |
---|
1602 | | - rtt_report->distance = (avg_dist >> 8) * 100; /* meter -> cm */ |
---|
1603 | | - rtt_report->distance += (avg_dist & 0xff) * 100 / 256; |
---|
| 2707 | + rtt_report->distance = (avg_dist >> 8) * 1000; /* meter -> mm */ |
---|
| 2708 | + rtt_report->distance += (avg_dist & 0xff) * 1000 / 256; |
---|
1604 | 2709 | } else { |
---|
1605 | 2710 | rtt_report->distance = FTM_INVALID; |
---|
1606 | 2711 | } |
---|
1607 | 2712 | /* time stamp */ |
---|
1608 | 2713 | /* get the time elapsed from boot time */ |
---|
1609 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) |
---|
1610 | | - ktime_get_boottime_ts64(&ts); |
---|
1611 | | -#else |
---|
| 2714 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) |
---|
1612 | 2715 | get_monotonic_boottime(&ts); |
---|
1613 | | -#endif |
---|
1614 | 2716 | rtt_report->ts = (uint64)TIMESPEC_TO_US(ts); |
---|
| 2717 | +#endif /* LINUX_VER >= 2.6.39 */ |
---|
1615 | 2718 | |
---|
1616 | 2719 | if (proxd_status == WL_PROXD_E_REMOTE_FAIL) { |
---|
1617 | 2720 | /* retry time after failure */ |
---|
.. | .. |
---|
1631 | 2734 | ftm_tmu_value_to_logstr(ltoh16_ua(&p_data_info->u.burst_duration.tmu)))); |
---|
1632 | 2735 | DHD_RTT(("rtt_report->burst_duration : %d\n", rtt_report->burst_duration)); |
---|
1633 | 2736 | } |
---|
| 2737 | + |
---|
| 2738 | + /* display detail if available */ |
---|
| 2739 | + num_rtt = ltoh16_ua(&p_data_info->num_rtt); |
---|
| 2740 | + if (num_rtt > 0) { |
---|
| 2741 | + DHD_RTT((">\tnum rtt: %d samples\n", num_rtt)); |
---|
| 2742 | + p_sample = &p_data_info->rtt[0]; |
---|
| 2743 | + for (i = 0; i < num_rtt; i++) { |
---|
| 2744 | + snr = 0; |
---|
| 2745 | + bitflips = 0; |
---|
| 2746 | + tof_phy_error = 0; |
---|
| 2747 | + tof_phy_tgt_error = 0; |
---|
| 2748 | + tof_target_snr = 0; |
---|
| 2749 | + tof_target_bitflips = 0; |
---|
| 2750 | + rssi = 0; |
---|
| 2751 | + dist = 0; |
---|
| 2752 | + num_ftm = p_data_info->num_ftm; |
---|
| 2753 | + /* FTM frames 1,4,7,11 have valid snr, rssi and bitflips */ |
---|
| 2754 | + if ((i % num_ftm) == 1) { |
---|
| 2755 | + rssi = (wl_proxd_rssi_t) ltoh16_ua(&p_sample->rssi); |
---|
| 2756 | + snr = (wl_proxd_snr_t) ltoh16_ua(&p_sample->snr); |
---|
| 2757 | + bitflips = (wl_proxd_bitflips_t) ltoh16_ua(&p_sample->bitflips); |
---|
| 2758 | + tof_phy_error = |
---|
| 2759 | + (wl_proxd_phy_error_t) |
---|
| 2760 | + ltoh32_ua(&p_sample->tof_phy_error); |
---|
| 2761 | + tof_phy_tgt_error = |
---|
| 2762 | + (wl_proxd_phy_error_t) |
---|
| 2763 | + ltoh32_ua(&p_sample->tof_tgt_phy_error); |
---|
| 2764 | + tof_target_snr = |
---|
| 2765 | + (wl_proxd_snr_t) |
---|
| 2766 | + ltoh16_ua(&p_sample->tof_tgt_snr); |
---|
| 2767 | + tof_target_bitflips = |
---|
| 2768 | + (wl_proxd_bitflips_t) |
---|
| 2769 | + ltoh16_ua(&p_sample->tof_tgt_bitflips); |
---|
| 2770 | + dist = ltoh32_ua(&p_sample->distance); |
---|
| 2771 | + } else { |
---|
| 2772 | + rssi = -1; |
---|
| 2773 | + snr = 0; |
---|
| 2774 | + bitflips = 0; |
---|
| 2775 | + dist = 0; |
---|
| 2776 | + tof_target_bitflips = 0; |
---|
| 2777 | + tof_target_snr = 0; |
---|
| 2778 | + tof_phy_tgt_error = 0; |
---|
| 2779 | + } |
---|
| 2780 | + DHD_RTT((">\t sample[%d]: id=%d rssi=%d snr=0x%x bitflips=%d" |
---|
| 2781 | + " tof_phy_error %x tof_phy_tgt_error %x target_snr=0x%x" |
---|
| 2782 | + " target_bitflips=%d dist=%d rtt=%d%s status %s" |
---|
| 2783 | + " Type %s coreid=%d\n", |
---|
| 2784 | + i, p_sample->id, rssi, snr, |
---|
| 2785 | + bitflips, tof_phy_error, tof_phy_tgt_error, |
---|
| 2786 | + tof_target_snr, |
---|
| 2787 | + tof_target_bitflips, dist, |
---|
| 2788 | + ltoh32_ua(&p_sample->rtt.intvl), |
---|
| 2789 | + ftm_tmu_value_to_logstr(ltoh16_ua(&p_sample->rtt.tmu)), |
---|
| 2790 | + ftm_status_value_to_logstr(ltoh32_ua(&p_sample->status)), |
---|
| 2791 | + ftm_frame_types[i % num_ftm], p_sample->coreid)); |
---|
| 2792 | + p_sample++; |
---|
| 2793 | + } |
---|
| 2794 | + } |
---|
1634 | 2795 | return err; |
---|
1635 | 2796 | } |
---|
| 2797 | + |
---|
| 2798 | +static int |
---|
| 2799 | +dhd_rtt_convert_results_to_host_v2(rtt_result_t *rtt_result, const uint8 *p_data, |
---|
| 2800 | + uint16 tlvid, uint16 len) |
---|
| 2801 | +{ |
---|
| 2802 | + int i; |
---|
| 2803 | + int err = BCME_OK; |
---|
| 2804 | + char eabuf[ETHER_ADDR_STR_LEN]; |
---|
| 2805 | + wl_proxd_result_flags_t flags; |
---|
| 2806 | + wl_proxd_session_state_t session_state; |
---|
| 2807 | + wl_proxd_status_t proxd_status; |
---|
| 2808 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) |
---|
| 2809 | + struct timespec64 ts; |
---|
| 2810 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) |
---|
| 2811 | + struct timespec ts; |
---|
| 2812 | +#endif /* LINUX_VER >= 2.6.39 */ |
---|
| 2813 | + uint32 ratespec; |
---|
| 2814 | + uint32 avg_dist; |
---|
| 2815 | + const wl_proxd_rtt_result_v2_t *p_data_info = NULL; |
---|
| 2816 | + const wl_proxd_rtt_sample_v2_t *p_sample_avg = NULL; |
---|
| 2817 | + const wl_proxd_rtt_sample_v2_t *p_sample = NULL; |
---|
| 2818 | + uint16 num_rtt = 0; |
---|
| 2819 | + wl_proxd_intvl_t rtt; |
---|
| 2820 | + wl_proxd_intvl_t p_time; |
---|
| 2821 | + uint16 snr = 0, bitflips = 0; |
---|
| 2822 | + wl_proxd_phy_error_t tof_phy_error = 0; |
---|
| 2823 | + wl_proxd_phy_error_t tof_phy_tgt_error = 0; |
---|
| 2824 | + wl_proxd_snr_t tof_target_snr = 0; |
---|
| 2825 | + wl_proxd_bitflips_t tof_target_bitflips = 0; |
---|
| 2826 | + int16 rssi = 0; |
---|
| 2827 | + int32 dist = 0; |
---|
| 2828 | + uint32 chanspec = 0; |
---|
| 2829 | + uint8 num_ftm = 0; |
---|
| 2830 | + char *ftm_frame_types[] = FTM_FRAME_TYPES; |
---|
| 2831 | + rtt_report_t *rtt_report = &(rtt_result->report); |
---|
| 2832 | + |
---|
| 2833 | + BCM_REFERENCE(ftm_frame_types); |
---|
| 2834 | + BCM_REFERENCE(dist); |
---|
| 2835 | + BCM_REFERENCE(rssi); |
---|
| 2836 | + BCM_REFERENCE(tof_target_bitflips); |
---|
| 2837 | + BCM_REFERENCE(tof_target_snr); |
---|
| 2838 | + BCM_REFERENCE(tof_phy_tgt_error); |
---|
| 2839 | + BCM_REFERENCE(tof_phy_error); |
---|
| 2840 | + BCM_REFERENCE(bitflips); |
---|
| 2841 | + BCM_REFERENCE(snr); |
---|
| 2842 | + BCM_REFERENCE(chanspec); |
---|
| 2843 | + BCM_REFERENCE(session_state); |
---|
| 2844 | + BCM_REFERENCE(ftm_session_state_value_to_logstr); |
---|
| 2845 | + |
---|
| 2846 | + NULL_CHECK(rtt_report, "rtt_report is NULL", err); |
---|
| 2847 | + NULL_CHECK(p_data, "p_data is NULL", err); |
---|
| 2848 | + DHD_RTT(("%s enter\n", __FUNCTION__)); |
---|
| 2849 | + p_data_info = (const wl_proxd_rtt_result_v2_t *) p_data; |
---|
| 2850 | + /* unpack and format 'flags' for display */ |
---|
| 2851 | + flags = ltoh16_ua(&p_data_info->flags); |
---|
| 2852 | + /* session state and status */ |
---|
| 2853 | + session_state = ltoh16_ua(&p_data_info->state); |
---|
| 2854 | + proxd_status = ltoh32_ua(&p_data_info->status); |
---|
| 2855 | + bcm_ether_ntoa((&(p_data_info->peer)), eabuf); |
---|
| 2856 | + |
---|
| 2857 | + if (proxd_status != BCME_OK) { |
---|
| 2858 | + DHD_RTT_ERR((">\tTarget(%s) session state=%d(%s), status=%d(%s) " |
---|
| 2859 | + "num_meas_ota %d num_valid_rtt %d result_flags %x\n", |
---|
| 2860 | + eabuf, session_state, |
---|
| 2861 | + ftm_session_state_value_to_logstr(session_state), |
---|
| 2862 | + proxd_status, ftm_status_value_to_logstr(proxd_status), |
---|
| 2863 | + p_data_info->num_meas, p_data_info->num_valid_rtt, |
---|
| 2864 | + p_data_info->flags)); |
---|
| 2865 | + } else { |
---|
| 2866 | + DHD_RTT((">\tTarget(%s) session state=%d(%s), status=%d(%s)\n", |
---|
| 2867 | + eabuf, session_state, |
---|
| 2868 | + ftm_session_state_value_to_logstr(session_state), |
---|
| 2869 | + proxd_status, ftm_status_value_to_logstr(proxd_status))); |
---|
| 2870 | + } |
---|
| 2871 | + /* show avg_dist (1/256m units), burst_num */ |
---|
| 2872 | + avg_dist = ltoh32_ua(&p_data_info->avg_dist); |
---|
| 2873 | + if (avg_dist == 0xffffffff) { /* report 'failure' case */ |
---|
| 2874 | + DHD_RTT((">\tavg_dist=-1m, burst_num=%d, valid_measure_cnt=%d\n", |
---|
| 2875 | + ltoh16_ua(&p_data_info->burst_num), |
---|
| 2876 | + p_data_info->num_valid_rtt)); /* in a session */ |
---|
| 2877 | + avg_dist = FTM_INVALID; |
---|
| 2878 | + } else { |
---|
| 2879 | + DHD_RTT((">\tavg_dist=%d.%04dm, burst_num=%d, valid_measure_cnt=%d num_ftm=%d " |
---|
| 2880 | + "num_meas_ota=%d, result_flags=%x\n", avg_dist >> 8, /* 1/256m units */ |
---|
| 2881 | + ((avg_dist & 0xff) * 625) >> 4, |
---|
| 2882 | + ltoh16_ua(&p_data_info->burst_num), |
---|
| 2883 | + p_data_info->num_valid_rtt, |
---|
| 2884 | + p_data_info->num_ftm, p_data_info->num_meas, |
---|
| 2885 | + p_data_info->flags)); /* in a session */ |
---|
| 2886 | + } |
---|
| 2887 | + rtt_result->rtt_detail.num_ota_meas = p_data_info->num_meas; |
---|
| 2888 | + rtt_result->rtt_detail.result_flags = p_data_info->flags; |
---|
| 2889 | + /* show 'avg_rtt' sample */ |
---|
| 2890 | + /* in v2, avg_rtt is the first element of the variable rtt[] */ |
---|
| 2891 | + p_sample_avg = &p_data_info->rtt[0]; |
---|
| 2892 | + ftm_tmu_value_to_logstr(ltoh16_ua(&p_sample_avg->rtt.tmu)); |
---|
| 2893 | + DHD_RTT((">\tavg_rtt sample: rssi=%d rtt=%d%s std_deviation =%d.%d" |
---|
| 2894 | + "ratespec=0x%08x chanspec=0x%08x\n", |
---|
| 2895 | + (int16) ltoh16_ua(&p_sample_avg->rssi), |
---|
| 2896 | + ltoh32_ua(&p_sample_avg->rtt.intvl), |
---|
| 2897 | + ftm_tmu_value_to_logstr(ltoh16_ua(&p_sample_avg->rtt.tmu)), |
---|
| 2898 | + ltoh16_ua(&p_data_info->sd_rtt)/10, ltoh16_ua(&p_data_info->sd_rtt)%10, |
---|
| 2899 | + ltoh32_ua(&p_sample_avg->ratespec), |
---|
| 2900 | + ltoh32_ua(&p_sample_avg->chanspec))); |
---|
| 2901 | + |
---|
| 2902 | + /* set peer address */ |
---|
| 2903 | + rtt_report->addr = p_data_info->peer; |
---|
| 2904 | + |
---|
| 2905 | + /* burst num */ |
---|
| 2906 | + rtt_report->burst_num = ltoh16_ua(&p_data_info->burst_num); |
---|
| 2907 | + |
---|
| 2908 | + /* success num */ |
---|
| 2909 | + rtt_report->success_num = p_data_info->num_valid_rtt; |
---|
| 2910 | + |
---|
| 2911 | + /* num-ftm configured */ |
---|
| 2912 | + rtt_report->ftm_num = p_data_info->num_ftm; |
---|
| 2913 | + |
---|
| 2914 | + /* actual number of FTM supported by peer */ |
---|
| 2915 | + rtt_report->num_per_burst_peer = p_data_info->num_ftm; |
---|
| 2916 | + rtt_report->negotiated_burst_num = p_data_info->num_ftm; |
---|
| 2917 | + |
---|
| 2918 | + /* status */ |
---|
| 2919 | + rtt_report->status = ftm_get_statusmap_info(proxd_status, |
---|
| 2920 | + &ftm_status_map_info[0], ARRAYSIZE(ftm_status_map_info)); |
---|
| 2921 | + |
---|
| 2922 | + /* Framework expects status as SUCCESS else all results will be |
---|
| 2923 | + * set to zero even if we have partial valid result. |
---|
| 2924 | + * So setting status as SUCCESS if we have a valid_rtt |
---|
| 2925 | + * On burst timeout we stop burst with "timeout" reason and |
---|
| 2926 | + * on msch end we set status as "cancel" |
---|
| 2927 | + */ |
---|
| 2928 | + if ((proxd_status == WL_PROXD_E_TIMEOUT || |
---|
| 2929 | + proxd_status == WL_PROXD_E_CANCELED) && |
---|
| 2930 | + rtt_report->success_num) { |
---|
| 2931 | + rtt_report->status = RTT_STATUS_SUCCESS; |
---|
| 2932 | + } |
---|
| 2933 | + |
---|
| 2934 | + /* rssi (0.5db) */ |
---|
| 2935 | + rtt_report->rssi = ABS((wl_proxd_rssi_t)ltoh16_ua(&p_sample_avg->rssi)) * 2; |
---|
| 2936 | + |
---|
| 2937 | + /* rx rate */ |
---|
| 2938 | + ratespec = ltoh32_ua(&p_sample_avg->ratespec); |
---|
| 2939 | + rtt_report->rx_rate = dhd_rtt_convert_rate_to_host(ratespec); |
---|
| 2940 | + |
---|
| 2941 | + /* tx rate */ |
---|
| 2942 | + if (flags & WL_PROXD_RESULT_FLAG_VHTACK) { |
---|
| 2943 | + rtt_report->tx_rate = dhd_rtt_convert_rate_to_host(0x2010010); |
---|
| 2944 | + } else { |
---|
| 2945 | + rtt_report->tx_rate = dhd_rtt_convert_rate_to_host(0xc); |
---|
| 2946 | + } |
---|
| 2947 | + |
---|
| 2948 | + /* rtt_sd */ |
---|
| 2949 | + rtt.tmu = ltoh16_ua(&p_sample_avg->rtt.tmu); |
---|
| 2950 | + rtt.intvl = ltoh32_ua(&p_sample_avg->rtt.intvl); |
---|
| 2951 | + rtt_report->rtt = (wifi_timespan)FTM_INTVL2NSEC(&rtt) * 1000; /* nano -> pico seconds */ |
---|
| 2952 | + rtt_report->rtt_sd = ltoh16_ua(&p_data_info->sd_rtt); /* nano -> 0.1 nano */ |
---|
| 2953 | + DHD_RTT(("rtt_report->rtt : %llu\n", rtt_report->rtt)); |
---|
| 2954 | + DHD_RTT(("rtt_report->rssi : %d (0.5db)\n", rtt_report->rssi)); |
---|
| 2955 | + |
---|
| 2956 | + /* average distance */ |
---|
| 2957 | + if (avg_dist != FTM_INVALID) { |
---|
| 2958 | + rtt_report->distance = (avg_dist >> 8) * 1000; /* meter -> mm */ |
---|
| 2959 | + rtt_report->distance += (avg_dist & 0xff) * 1000 / 256; |
---|
| 2960 | + /* rtt_sd is in 0.1 ns. |
---|
| 2961 | + * host needs distance_sd in milli mtrs |
---|
| 2962 | + * (0.1 * rtt_sd/2 * 10^-9) * C * 1000 |
---|
| 2963 | + */ |
---|
| 2964 | + rtt_report->distance_sd = rtt_report->rtt_sd * 15; /* mm */ |
---|
| 2965 | + } else { |
---|
| 2966 | + rtt_report->distance = FTM_INVALID; |
---|
| 2967 | + } |
---|
| 2968 | + /* time stamp */ |
---|
| 2969 | + /* get the time elapsed from boot time */ |
---|
| 2970 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) |
---|
| 2971 | + get_monotonic_boottime(&ts); |
---|
| 2972 | + rtt_report->ts = (uint64)TIMESPEC_TO_US(ts); |
---|
| 2973 | +#endif /* LINUX_VER >= 2.6.39 */ |
---|
| 2974 | + |
---|
| 2975 | + if (proxd_status == WL_PROXD_E_REMOTE_FAIL) { |
---|
| 2976 | + /* retry time after failure */ |
---|
| 2977 | + p_time.intvl = ltoh32_ua(&p_data_info->u.retry_after.intvl); |
---|
| 2978 | + p_time.tmu = ltoh16_ua(&p_data_info->u.retry_after.tmu); |
---|
| 2979 | + rtt_report->retry_after_duration = FTM_INTVL2SEC(&p_time); /* s -> s */ |
---|
| 2980 | + DHD_RTT((">\tretry_after: %d%s\n", |
---|
| 2981 | + ltoh32_ua(&p_data_info->u.retry_after.intvl), |
---|
| 2982 | + ftm_tmu_value_to_logstr(ltoh16_ua(&p_data_info->u.retry_after.tmu)))); |
---|
| 2983 | + } else { |
---|
| 2984 | + /* burst duration */ |
---|
| 2985 | + p_time.intvl = ltoh32_ua(&p_data_info->u.retry_after.intvl); |
---|
| 2986 | + p_time.tmu = ltoh16_ua(&p_data_info->u.retry_after.tmu); |
---|
| 2987 | + rtt_report->burst_duration = FTM_INTVL2MSEC(&p_time); /* s -> ms */ |
---|
| 2988 | + DHD_RTT((">\tburst_duration: %d%s\n", |
---|
| 2989 | + ltoh32_ua(&p_data_info->u.burst_duration.intvl), |
---|
| 2990 | + ftm_tmu_value_to_logstr(ltoh16_ua(&p_data_info->u.burst_duration.tmu)))); |
---|
| 2991 | + DHD_RTT(("rtt_report->burst_duration : %d\n", rtt_report->burst_duration)); |
---|
| 2992 | + } |
---|
| 2993 | + /* display detail if available */ |
---|
| 2994 | + num_rtt = ltoh16_ua(&p_data_info->num_rtt); |
---|
| 2995 | + if (num_rtt > 0) { |
---|
| 2996 | + DHD_RTT((">\tnum rtt: %d samples\n", num_rtt)); |
---|
| 2997 | + p_sample = &p_data_info->rtt[1]; |
---|
| 2998 | + for (i = 0; i < num_rtt; i++) { |
---|
| 2999 | + snr = 0; |
---|
| 3000 | + bitflips = 0; |
---|
| 3001 | + tof_phy_error = 0; |
---|
| 3002 | + tof_phy_tgt_error = 0; |
---|
| 3003 | + tof_target_snr = 0; |
---|
| 3004 | + tof_target_bitflips = 0; |
---|
| 3005 | + rssi = 0; |
---|
| 3006 | + dist = 0; |
---|
| 3007 | + num_ftm = p_data_info->num_ftm; |
---|
| 3008 | + /* FTM frames 1,4,7,11 have valid snr, rssi and bitflips */ |
---|
| 3009 | + if ((i % num_ftm) == 1) { |
---|
| 3010 | + rssi = (wl_proxd_rssi_t) ltoh16_ua(&p_sample->rssi); |
---|
| 3011 | + snr = (wl_proxd_snr_t) ltoh16_ua(&p_sample->snr); |
---|
| 3012 | + bitflips = (wl_proxd_bitflips_t) ltoh16_ua(&p_sample->bitflips); |
---|
| 3013 | + tof_phy_error = |
---|
| 3014 | + (wl_proxd_phy_error_t) |
---|
| 3015 | + ltoh32_ua(&p_sample->tof_phy_error); |
---|
| 3016 | + tof_phy_tgt_error = |
---|
| 3017 | + (wl_proxd_phy_error_t) |
---|
| 3018 | + ltoh32_ua(&p_sample->tof_tgt_phy_error); |
---|
| 3019 | + tof_target_snr = |
---|
| 3020 | + (wl_proxd_snr_t) |
---|
| 3021 | + ltoh16_ua(&p_sample->tof_tgt_snr); |
---|
| 3022 | + tof_target_bitflips = |
---|
| 3023 | + (wl_proxd_bitflips_t) |
---|
| 3024 | + ltoh16_ua(&p_sample->tof_tgt_bitflips); |
---|
| 3025 | + dist = ltoh32_ua(&p_sample->distance); |
---|
| 3026 | + chanspec = ltoh32_ua(&p_sample->chanspec); |
---|
| 3027 | + } else { |
---|
| 3028 | + rssi = -1; |
---|
| 3029 | + snr = 0; |
---|
| 3030 | + bitflips = 0; |
---|
| 3031 | + dist = 0; |
---|
| 3032 | + tof_target_bitflips = 0; |
---|
| 3033 | + tof_target_snr = 0; |
---|
| 3034 | + tof_phy_tgt_error = 0; |
---|
| 3035 | + } |
---|
| 3036 | + DHD_RTT((">\t sample[%d]: id=%d rssi=%d snr=0x%x bitflips=%d" |
---|
| 3037 | + " tof_phy_error %x tof_phy_tgt_error %x target_snr=0x%x" |
---|
| 3038 | + " target_bitflips=%d dist=%d rtt=%d%s status %s Type %s" |
---|
| 3039 | + " coreid=%d chanspec=0x%08x\n", |
---|
| 3040 | + i, p_sample->id, rssi, snr, |
---|
| 3041 | + bitflips, tof_phy_error, tof_phy_tgt_error, |
---|
| 3042 | + tof_target_snr, |
---|
| 3043 | + tof_target_bitflips, dist, |
---|
| 3044 | + ltoh32_ua(&p_sample->rtt.intvl), |
---|
| 3045 | + ftm_tmu_value_to_logstr(ltoh16_ua(&p_sample->rtt.tmu)), |
---|
| 3046 | + ftm_status_value_to_logstr(ltoh32_ua(&p_sample->status)), |
---|
| 3047 | + ftm_frame_types[i % num_ftm], p_sample->coreid, |
---|
| 3048 | + chanspec)); |
---|
| 3049 | + p_sample++; |
---|
| 3050 | + } |
---|
| 3051 | + } |
---|
| 3052 | + return err; |
---|
| 3053 | +} |
---|
| 3054 | +#ifdef WL_CFG80211 |
---|
| 3055 | +/* Common API for handling Session End. |
---|
| 3056 | +* This API will flush out the results for a peer MAC. |
---|
| 3057 | +* |
---|
| 3058 | +* @For legacy FTM session, this API will be called |
---|
| 3059 | +* when legacy FTM_SESSION_END event is received. |
---|
| 3060 | +* @For legacy Nan-RTT , this API will be called when |
---|
| 3061 | +* we are cancelling the nan-ranging session or on |
---|
| 3062 | +* nan-ranging-end event. |
---|
| 3063 | +*/ |
---|
| 3064 | +static void |
---|
| 3065 | +dhd_rtt_handle_rtt_session_end(dhd_pub_t *dhd) |
---|
| 3066 | +{ |
---|
| 3067 | + |
---|
| 3068 | + int idx; |
---|
| 3069 | + struct rtt_noti_callback *iter; |
---|
| 3070 | + rtt_results_header_t *entry, *next; |
---|
| 3071 | + rtt_result_t *next2; |
---|
| 3072 | + rtt_result_t *rtt_result; |
---|
| 3073 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 3074 | + |
---|
| 3075 | + /* Cancel pending proxd timeout work if any */ |
---|
| 3076 | + if (delayed_work_pending(&rtt_status->proxd_timeout)) { |
---|
| 3077 | + cancel_delayed_work(&rtt_status->proxd_timeout); |
---|
| 3078 | + } |
---|
| 3079 | + |
---|
| 3080 | + /* find next target to trigger RTT */ |
---|
| 3081 | + for (idx = (rtt_status->cur_idx + 1); |
---|
| 3082 | + idx < rtt_status->rtt_config.rtt_target_cnt; idx++) { |
---|
| 3083 | + /* skip the disabled device */ |
---|
| 3084 | + if (rtt_status->rtt_config.target_info[idx].disable) { |
---|
| 3085 | + continue; |
---|
| 3086 | + } else { |
---|
| 3087 | + /* set the idx to cur_idx */ |
---|
| 3088 | + rtt_status->cur_idx = idx; |
---|
| 3089 | + break; |
---|
| 3090 | + } |
---|
| 3091 | + } |
---|
| 3092 | + if (idx < rtt_status->rtt_config.rtt_target_cnt) { |
---|
| 3093 | + /* restart to measure RTT from next device */ |
---|
| 3094 | + DHD_INFO(("restart to measure rtt\n")); |
---|
| 3095 | + schedule_work(&rtt_status->work); |
---|
| 3096 | + } else { |
---|
| 3097 | + DHD_RTT(("RTT_STOPPED\n")); |
---|
| 3098 | + rtt_status->status = RTT_STOPPED; |
---|
| 3099 | + /* notify the completed information to others */ |
---|
| 3100 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
| 3101 | + list_for_each_entry(iter, &rtt_status->noti_fn_list, list) { |
---|
| 3102 | + iter->noti_fn(iter->ctx, &rtt_status->rtt_results_cache); |
---|
| 3103 | + } |
---|
| 3104 | + /* remove the rtt results in cache */ |
---|
| 3105 | + if (!list_empty(&rtt_status->rtt_results_cache)) { |
---|
| 3106 | + /* Iterate rtt_results_header list */ |
---|
| 3107 | + list_for_each_entry_safe(entry, next, |
---|
| 3108 | + &rtt_status->rtt_results_cache, list) { |
---|
| 3109 | + list_del(&entry->list); |
---|
| 3110 | + /* Iterate rtt_result list */ |
---|
| 3111 | + list_for_each_entry_safe(rtt_result, next2, |
---|
| 3112 | + &entry->result_list, list) { |
---|
| 3113 | + list_del(&rtt_result->list); |
---|
| 3114 | + kfree(rtt_result); |
---|
| 3115 | + } |
---|
| 3116 | + kfree(entry); |
---|
| 3117 | + } |
---|
| 3118 | + } |
---|
| 3119 | + GCC_DIAGNOSTIC_POP(); |
---|
| 3120 | + /* reinitialize the HEAD */ |
---|
| 3121 | + INIT_LIST_HEAD(&rtt_status->rtt_results_cache); |
---|
| 3122 | + /* clear information for rtt_config */ |
---|
| 3123 | + rtt_status->rtt_config.rtt_target_cnt = 0; |
---|
| 3124 | + memset_s(rtt_status->rtt_config.target_info, TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT), |
---|
| 3125 | + 0, TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT)); |
---|
| 3126 | + rtt_status->cur_idx = 0; |
---|
| 3127 | + } |
---|
| 3128 | +} |
---|
| 3129 | +#endif /* WL_CFG80211 */ |
---|
| 3130 | + |
---|
| 3131 | +#ifdef WL_CFG80211 |
---|
| 3132 | +static int |
---|
| 3133 | +dhd_rtt_create_failure_result(rtt_status_info_t *rtt_status, |
---|
| 3134 | + struct ether_addr *addr) |
---|
| 3135 | +{ |
---|
| 3136 | + rtt_results_header_t *rtt_results_header = NULL; |
---|
| 3137 | + rtt_target_info_t *rtt_target_info; |
---|
| 3138 | + int ret = BCME_OK; |
---|
| 3139 | + rtt_result_t *rtt_result; |
---|
| 3140 | + |
---|
| 3141 | + /* allocate new header for rtt_results */ |
---|
| 3142 | + rtt_results_header = (rtt_results_header_t *)MALLOCZ(rtt_status->dhd->osh, |
---|
| 3143 | + sizeof(rtt_results_header_t)); |
---|
| 3144 | + if (!rtt_results_header) { |
---|
| 3145 | + ret = -ENOMEM; |
---|
| 3146 | + goto exit; |
---|
| 3147 | + } |
---|
| 3148 | + rtt_target_info = &rtt_status->rtt_config.target_info[rtt_status->cur_idx]; |
---|
| 3149 | + /* Initialize the head of list for rtt result */ |
---|
| 3150 | + INIT_LIST_HEAD(&rtt_results_header->result_list); |
---|
| 3151 | + /* same src and dest len */ |
---|
| 3152 | + (void)memcpy_s(&rtt_results_header->peer_mac, |
---|
| 3153 | + ETHER_ADDR_LEN, addr, ETHER_ADDR_LEN); |
---|
| 3154 | + list_add_tail(&rtt_results_header->list, &rtt_status->rtt_results_cache); |
---|
| 3155 | + |
---|
| 3156 | + /* allocate rtt_results for new results */ |
---|
| 3157 | + rtt_result = (rtt_result_t *)MALLOCZ(rtt_status->dhd->osh, |
---|
| 3158 | + sizeof(rtt_result_t)); |
---|
| 3159 | + if (!rtt_result) { |
---|
| 3160 | + ret = -ENOMEM; |
---|
| 3161 | + kfree(rtt_results_header); |
---|
| 3162 | + goto exit; |
---|
| 3163 | + } |
---|
| 3164 | + /* fill out the results from the configuration param */ |
---|
| 3165 | + rtt_result->report.ftm_num = rtt_target_info->num_frames_per_burst; |
---|
| 3166 | + rtt_result->report.type = RTT_TWO_WAY; |
---|
| 3167 | + DHD_RTT(("report->ftm_num : %d\n", rtt_result->report.ftm_num)); |
---|
| 3168 | + rtt_result->report_len = RTT_REPORT_SIZE; |
---|
| 3169 | + rtt_result->report.status = RTT_STATUS_FAIL_NO_RSP; |
---|
| 3170 | + /* same src and dest len */ |
---|
| 3171 | + (void)memcpy_s(&rtt_result->report.addr, ETHER_ADDR_LEN, |
---|
| 3172 | + &rtt_target_info->addr, ETHER_ADDR_LEN); |
---|
| 3173 | + rtt_result->report.distance = FTM_INVALID; |
---|
| 3174 | + list_add_tail(&rtt_result->list, &rtt_results_header->result_list); |
---|
| 3175 | + rtt_results_header->result_cnt++; |
---|
| 3176 | + rtt_results_header->result_tot_len += rtt_result->report_len; |
---|
| 3177 | +exit: |
---|
| 3178 | + return ret; |
---|
| 3179 | +} |
---|
| 3180 | + |
---|
| 3181 | +static bool |
---|
| 3182 | +dhd_rtt_get_report_header(rtt_status_info_t *rtt_status, |
---|
| 3183 | + rtt_results_header_t **rtt_results_header, struct ether_addr *addr) |
---|
| 3184 | +{ |
---|
| 3185 | + rtt_results_header_t *entry; |
---|
| 3186 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
| 3187 | + /* find a rtt_report_header for this mac address */ |
---|
| 3188 | + list_for_each_entry(entry, &rtt_status->rtt_results_cache, list) { |
---|
| 3189 | + GCC_DIAGNOSTIC_POP(); |
---|
| 3190 | + if (!memcmp(&entry->peer_mac, addr, ETHER_ADDR_LEN)) { |
---|
| 3191 | + /* found a rtt_report_header for peer_mac in the list */ |
---|
| 3192 | + if (rtt_results_header) { |
---|
| 3193 | + *rtt_results_header = entry; |
---|
| 3194 | + } |
---|
| 3195 | + return TRUE; |
---|
| 3196 | + } |
---|
| 3197 | + } |
---|
| 3198 | + return FALSE; |
---|
| 3199 | +} |
---|
| 3200 | + |
---|
| 3201 | +int |
---|
| 3202 | +dhd_rtt_handle_nan_rtt_session_end(dhd_pub_t *dhd, struct ether_addr *peer) |
---|
| 3203 | +{ |
---|
| 3204 | + bool is_new = TRUE; |
---|
| 3205 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 3206 | + mutex_lock(&rtt_status->rtt_mutex); |
---|
| 3207 | + is_new = !dhd_rtt_get_report_header(rtt_status, NULL, peer); |
---|
| 3208 | + |
---|
| 3209 | + if (is_new) { /* no FTM result..create failure result */ |
---|
| 3210 | + dhd_rtt_create_failure_result(rtt_status, peer); |
---|
| 3211 | + } |
---|
| 3212 | + dhd_rtt_handle_rtt_session_end(dhd); |
---|
| 3213 | + mutex_unlock(&rtt_status->rtt_mutex); |
---|
| 3214 | + return BCME_OK; |
---|
| 3215 | +} |
---|
| 3216 | +#endif /* WL_CFG80211 */ |
---|
| 3217 | + |
---|
| 3218 | +static bool |
---|
| 3219 | +dhd_rtt_is_valid_measurement(rtt_result_t *rtt_result) |
---|
| 3220 | +{ |
---|
| 3221 | + bool ret = FALSE; |
---|
| 3222 | + |
---|
| 3223 | + if (rtt_result && (rtt_result->report.success_num != 0)) { |
---|
| 3224 | + ret = TRUE; |
---|
| 3225 | + } |
---|
| 3226 | + return ret; |
---|
| 3227 | +} |
---|
| 3228 | + |
---|
| 3229 | +static int |
---|
| 3230 | +dhd_rtt_parse_result_event(wl_proxd_event_t *proxd_ev_data, |
---|
| 3231 | + int tlvs_len, rtt_result_t *rtt_result) |
---|
| 3232 | +{ |
---|
| 3233 | + int ret = BCME_OK; |
---|
| 3234 | + |
---|
| 3235 | + /* unpack TLVs and invokes the cbfn to print the event content TLVs */ |
---|
| 3236 | + ret = bcm_unpack_xtlv_buf((void *) rtt_result, |
---|
| 3237 | + (uint8 *)&proxd_ev_data->tlvs[0], tlvs_len, |
---|
| 3238 | + BCM_XTLV_OPTION_ALIGN32, rtt_unpack_xtlv_cbfn); |
---|
| 3239 | + if (ret != BCME_OK) { |
---|
| 3240 | + DHD_RTT_ERR(("%s : Failed to unpack xtlv for an event\n", |
---|
| 3241 | + __FUNCTION__)); |
---|
| 3242 | + goto exit; |
---|
| 3243 | + } |
---|
| 3244 | + /* fill out the results from the configuration param */ |
---|
| 3245 | + rtt_result->report.type = RTT_TWO_WAY; |
---|
| 3246 | + DHD_RTT(("report->ftm_num : %d\n", rtt_result->report.ftm_num)); |
---|
| 3247 | + rtt_result->report_len = RTT_REPORT_SIZE; |
---|
| 3248 | + rtt_result->detail_len = sizeof(rtt_result->rtt_detail); |
---|
| 3249 | + |
---|
| 3250 | +exit: |
---|
| 3251 | + return ret; |
---|
| 3252 | + |
---|
| 3253 | +} |
---|
| 3254 | + |
---|
| 3255 | +static int |
---|
| 3256 | +dhd_rtt_handle_directed_rtt_burst_end(dhd_pub_t *dhd, struct ether_addr *peer_addr, |
---|
| 3257 | + wl_proxd_event_t *proxd_ev_data, int tlvs_len, rtt_result_t *rtt_result, bool is_nan) |
---|
| 3258 | +{ |
---|
| 3259 | + rtt_status_info_t *rtt_status; |
---|
| 3260 | + rtt_results_header_t *rtt_results_header = NULL; |
---|
| 3261 | + bool is_new = TRUE; |
---|
| 3262 | + int ret = BCME_OK; |
---|
| 3263 | + int err_at = 0; |
---|
| 3264 | + |
---|
| 3265 | + rtt_status = GET_RTTSTATE(dhd); |
---|
| 3266 | + is_new = !dhd_rtt_get_report_header(rtt_status, |
---|
| 3267 | + &rtt_results_header, peer_addr); |
---|
| 3268 | + |
---|
| 3269 | + if (tlvs_len > 0) { |
---|
| 3270 | + if (is_new) { |
---|
| 3271 | + /* allocate new header for rtt_results */ |
---|
| 3272 | + rtt_results_header = (rtt_results_header_t *)MALLOCZ(rtt_status->dhd->osh, |
---|
| 3273 | + sizeof(rtt_results_header_t)); |
---|
| 3274 | + if (!rtt_results_header) { |
---|
| 3275 | + ret = BCME_NORESOURCE; |
---|
| 3276 | + err_at = 1; |
---|
| 3277 | + goto exit; |
---|
| 3278 | + } |
---|
| 3279 | + /* Initialize the head of list for rtt result */ |
---|
| 3280 | + INIT_LIST_HEAD(&rtt_results_header->result_list); |
---|
| 3281 | + /* same src and header len */ |
---|
| 3282 | + (void)memcpy_s(&rtt_results_header->peer_mac, ETHER_ADDR_LEN, |
---|
| 3283 | + peer_addr, ETHER_ADDR_LEN); |
---|
| 3284 | + list_add_tail(&rtt_results_header->list, &rtt_status->rtt_results_cache); |
---|
| 3285 | + } |
---|
| 3286 | + |
---|
| 3287 | + ret = dhd_rtt_parse_result_event(proxd_ev_data, tlvs_len, rtt_result); |
---|
| 3288 | + if ((ret == BCME_OK) && ((!is_nan) || |
---|
| 3289 | + dhd_rtt_is_valid_measurement(rtt_result))) { |
---|
| 3290 | + /* |
---|
| 3291 | + * Add to list, if non-nan RTT (legacy) or |
---|
| 3292 | + * valid measurement in nan rtt case |
---|
| 3293 | + */ |
---|
| 3294 | + list_add_tail(&rtt_result->list, &rtt_results_header->result_list); |
---|
| 3295 | + rtt_results_header->result_cnt++; |
---|
| 3296 | + rtt_results_header->result_tot_len += rtt_result->report_len + |
---|
| 3297 | + rtt_result->detail_len; |
---|
| 3298 | + } else { |
---|
| 3299 | + err_at = 2; |
---|
| 3300 | + if (ret == BCME_OK) { |
---|
| 3301 | + /* Case for nan rtt invalid measurement */ |
---|
| 3302 | + ret = BCME_ERROR; |
---|
| 3303 | + err_at = 3; |
---|
| 3304 | + } |
---|
| 3305 | + goto exit; |
---|
| 3306 | + } |
---|
| 3307 | + } else { |
---|
| 3308 | + ret = BCME_ERROR; |
---|
| 3309 | + err_at = 4; |
---|
| 3310 | + goto exit; |
---|
| 3311 | + } |
---|
| 3312 | + |
---|
| 3313 | +exit: |
---|
| 3314 | + if (ret != BCME_OK) { |
---|
| 3315 | + DHD_RTT_ERR(("dhd_rtt_handle_directed_rtt_burst_end: failed, " |
---|
| 3316 | + " ret = %d, err_at = %d\n", ret, err_at)); |
---|
| 3317 | + if (rtt_results_header) { |
---|
| 3318 | + list_del(&rtt_results_header->list); |
---|
| 3319 | + kfree(rtt_results_header); |
---|
| 3320 | + rtt_results_header = NULL; |
---|
| 3321 | + } |
---|
| 3322 | + } |
---|
| 3323 | + return ret; |
---|
| 3324 | +} |
---|
| 3325 | + |
---|
| 3326 | +#ifdef WL_NAN |
---|
| 3327 | +static void |
---|
| 3328 | +dhd_rtt_nan_range_report(struct bcm_cfg80211 *cfg, |
---|
| 3329 | + rtt_result_t *rtt_result) |
---|
| 3330 | +{ |
---|
| 3331 | + wl_nan_ev_rng_rpt_ind_t range_res; |
---|
| 3332 | + nan_ranging_inst_t *rng_inst = NULL; |
---|
| 3333 | + dhd_pub_t *dhd = (struct dhd_pub *)(cfg->pub); |
---|
| 3334 | + rtt_status_info_t *rtt_status = GET_RTTSTATE(dhd); |
---|
| 3335 | + |
---|
| 3336 | + UNUSED_PARAMETER(range_res); |
---|
| 3337 | + |
---|
| 3338 | + if (!dhd_rtt_is_valid_measurement(rtt_result)) { |
---|
| 3339 | + /* Drop Invalid Measurements for NAN RTT report */ |
---|
| 3340 | + DHD_RTT(("dhd_rtt_nan_range_report: Drop Invalid Measurements\n")); |
---|
| 3341 | + return; |
---|
| 3342 | + } |
---|
| 3343 | + bzero(&range_res, sizeof(range_res)); |
---|
| 3344 | + range_res.indication = 0; |
---|
| 3345 | + range_res.dist_mm = rtt_result->report.distance; |
---|
| 3346 | + /* same src and header len, ignoring ret val here */ |
---|
| 3347 | + (void)memcpy_s(&range_res.peer_m_addr, ETHER_ADDR_LEN, |
---|
| 3348 | + &rtt_result->report.addr, ETHER_ADDR_LEN); |
---|
| 3349 | + wl_cfgnan_process_range_report(cfg, &range_res); |
---|
| 3350 | + /* |
---|
| 3351 | + * suspend geofence ranging for this target |
---|
| 3352 | + * and move to next target |
---|
| 3353 | + * after valid measurement for the target |
---|
| 3354 | + */ |
---|
| 3355 | + rng_inst = wl_cfgnan_check_for_ranging(cfg, &range_res.peer_m_addr); |
---|
| 3356 | + if (rng_inst) { |
---|
| 3357 | + wl_cfgnan_suspend_geofence_rng_session(bcmcfg_to_prmry_ndev(cfg), |
---|
| 3358 | + &rng_inst->peer_addr, RTT_GEO_SUSPN_RANGE_RES_REPORTED, 0); |
---|
| 3359 | + GEOFENCE_RTT_LOCK(rtt_status); |
---|
| 3360 | + dhd_rtt_move_geofence_cur_target_idx_to_next(dhd); |
---|
| 3361 | + GEOFENCE_RTT_UNLOCK(rtt_status); |
---|
| 3362 | + wl_cfgnan_reset_geofence_ranging(cfg, |
---|
| 3363 | + rng_inst, RTT_SCHED_RNG_RPT_GEOFENCE); |
---|
| 3364 | + } |
---|
| 3365 | +} |
---|
| 3366 | + |
---|
| 3367 | +static int |
---|
| 3368 | +dhd_rtt_handle_nan_burst_end(dhd_pub_t *dhd, struct ether_addr *peer_addr, |
---|
| 3369 | + wl_proxd_event_t *proxd_ev_data, int tlvs_len) |
---|
| 3370 | +{ |
---|
| 3371 | + struct net_device *ndev = NULL; |
---|
| 3372 | + struct bcm_cfg80211 *cfg = NULL; |
---|
| 3373 | + nan_ranging_inst_t *rng_inst = NULL; |
---|
| 3374 | + rtt_status_info_t *rtt_status = NULL; |
---|
| 3375 | + rtt_result_t *rtt_result = NULL; |
---|
| 3376 | + bool is_geofence = FALSE; |
---|
| 3377 | + int ret = BCME_OK; |
---|
| 3378 | + |
---|
| 3379 | + ndev = dhd_linux_get_primary_netdev(dhd); |
---|
| 3380 | + cfg = wiphy_priv(ndev->ieee80211_ptr->wiphy); |
---|
| 3381 | + |
---|
| 3382 | + rtt_status = GET_RTTSTATE(dhd); |
---|
| 3383 | + NULL_CHECK(rtt_status, "rtt_status is NULL", ret); |
---|
| 3384 | + NAN_MUTEX_LOCK(); |
---|
| 3385 | + mutex_lock(&rtt_status->rtt_mutex); |
---|
| 3386 | + |
---|
| 3387 | + if ((cfg->nan_enable == FALSE) || |
---|
| 3388 | + ETHER_ISNULLADDR(peer_addr)) { |
---|
| 3389 | + DHD_RTT_ERR(("Received Burst End with NULL ether addr, " |
---|
| 3390 | + "or nan disable, nan_enable = %d\n", cfg->nan_enable)); |
---|
| 3391 | + ret = BCME_UNSUPPORTED; |
---|
| 3392 | + goto exit; |
---|
| 3393 | + } |
---|
| 3394 | + |
---|
| 3395 | + rng_inst = wl_cfgnan_check_for_ranging(cfg, peer_addr); |
---|
| 3396 | + if (rng_inst) { |
---|
| 3397 | + is_geofence = (rng_inst->range_type |
---|
| 3398 | + == RTT_TYPE_NAN_GEOFENCE); |
---|
| 3399 | + } else { |
---|
| 3400 | + DHD_RTT_ERR(("Received Burst End without Ranging Instance\n")); |
---|
| 3401 | + ret = BCME_ERROR; |
---|
| 3402 | + goto exit; |
---|
| 3403 | + } |
---|
| 3404 | + |
---|
| 3405 | + /* allocate rtt_results for new results */ |
---|
| 3406 | + rtt_result = (rtt_result_t *)MALLOCZ(dhd->osh, sizeof(rtt_result_t)); |
---|
| 3407 | + if (!rtt_result) { |
---|
| 3408 | + ret = BCME_NORESOURCE; |
---|
| 3409 | + goto exit; |
---|
| 3410 | + } |
---|
| 3411 | + |
---|
| 3412 | + if (is_geofence) { |
---|
| 3413 | + ret = dhd_rtt_parse_result_event(proxd_ev_data, tlvs_len, rtt_result); |
---|
| 3414 | + if (ret != BCME_OK) { |
---|
| 3415 | + DHD_RTT_ERR(("avilog: dhd_rtt_handle_nan_burst_end: " |
---|
| 3416 | + "dhd_rtt_parse_result_event failed\n")); |
---|
| 3417 | + goto exit; |
---|
| 3418 | + } |
---|
| 3419 | + } else { |
---|
| 3420 | + if (RTT_IS_STOPPED(rtt_status)) { |
---|
| 3421 | + /* Ignore the Proxd event */ |
---|
| 3422 | + DHD_RTT((" event handler rtt is stopped \n")); |
---|
| 3423 | + if (rtt_status->flags == WL_PROXD_SESSION_FLAG_TARGET) { |
---|
| 3424 | + DHD_RTT(("Device is target/Responder. Recv the event. \n")); |
---|
| 3425 | + } else { |
---|
| 3426 | + ret = BCME_UNSUPPORTED; |
---|
| 3427 | + goto exit; |
---|
| 3428 | + } |
---|
| 3429 | + } |
---|
| 3430 | + ret = dhd_rtt_handle_directed_rtt_burst_end(dhd, peer_addr, |
---|
| 3431 | + proxd_ev_data, tlvs_len, rtt_result, TRUE); |
---|
| 3432 | + if (ret != BCME_OK) { |
---|
| 3433 | + goto exit; |
---|
| 3434 | + } |
---|
| 3435 | + |
---|
| 3436 | + } |
---|
| 3437 | + |
---|
| 3438 | +exit: |
---|
| 3439 | + mutex_unlock(&rtt_status->rtt_mutex); |
---|
| 3440 | + if (ret == BCME_OK) { |
---|
| 3441 | + dhd_rtt_nan_range_report(cfg, rtt_result); |
---|
| 3442 | + } |
---|
| 3443 | + if (rtt_result && |
---|
| 3444 | + ((ret != BCME_OK) || is_geofence)) { |
---|
| 3445 | + kfree(rtt_result); |
---|
| 3446 | + rtt_result = NULL; |
---|
| 3447 | + } |
---|
| 3448 | + NAN_MUTEX_UNLOCK(); |
---|
| 3449 | + return ret; |
---|
| 3450 | +} |
---|
| 3451 | +#endif /* WL_NAN */ |
---|
1636 | 3452 | |
---|
1637 | 3453 | int |
---|
1638 | 3454 | dhd_rtt_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data) |
---|
1639 | 3455 | { |
---|
1640 | 3456 | int ret = BCME_OK; |
---|
1641 | 3457 | int tlvs_len; |
---|
1642 | | - int idx; |
---|
1643 | 3458 | uint16 version; |
---|
1644 | 3459 | wl_proxd_event_t *p_event; |
---|
1645 | 3460 | wl_proxd_event_type_t event_type; |
---|
1646 | 3461 | wl_proxd_ftm_session_status_t session_status; |
---|
1647 | 3462 | const ftm_strmap_entry_t *p_loginfo; |
---|
| 3463 | + rtt_result_t *rtt_result; |
---|
| 3464 | +#ifdef WL_CFG80211 |
---|
1648 | 3465 | rtt_status_info_t *rtt_status; |
---|
1649 | | - rtt_target_info_t *rtt_target_info; |
---|
1650 | | - struct rtt_noti_callback *iter; |
---|
1651 | | - rtt_results_header_t *entry, *next, *rtt_results_header = NULL; |
---|
1652 | | - rtt_result_t *rtt_result, *next2; |
---|
1653 | | - gfp_t kflags; |
---|
| 3466 | + rtt_results_header_t *rtt_results_header = NULL; |
---|
1654 | 3467 | bool is_new = TRUE; |
---|
| 3468 | +#endif /* WL_CFG80211 */ |
---|
1655 | 3469 | |
---|
| 3470 | + DHD_RTT(("Enter %s \n", __FUNCTION__)); |
---|
1656 | 3471 | NULL_CHECK(dhd, "dhd is NULL", ret); |
---|
1657 | | - rtt_status = GET_RTTSTATE(dhd); |
---|
1658 | | - NULL_CHECK(rtt_status, "rtt_status is NULL", ret); |
---|
1659 | 3472 | |
---|
1660 | 3473 | if (ntoh32_ua((void *)&event->datalen) < OFFSETOF(wl_proxd_event_t, tlvs)) { |
---|
1661 | 3474 | DHD_RTT(("%s: wrong datalen:%d\n", __FUNCTION__, |
---|
.. | .. |
---|
1664 | 3477 | } |
---|
1665 | 3478 | event_type = ntoh32_ua((void *)&event->event_type); |
---|
1666 | 3479 | if (event_type != WLC_E_PROXD) { |
---|
1667 | | - DHD_ERROR((" failed event \n")); |
---|
| 3480 | + DHD_RTT_ERR((" failed event \n")); |
---|
1668 | 3481 | return -EINVAL; |
---|
1669 | 3482 | } |
---|
1670 | 3483 | |
---|
1671 | 3484 | if (!event_data) { |
---|
1672 | | - DHD_ERROR(("%s: event_data:NULL\n", __FUNCTION__)); |
---|
| 3485 | + DHD_RTT_ERR(("%s: event_data:NULL\n", __FUNCTION__)); |
---|
1673 | 3486 | return -EINVAL; |
---|
1674 | | - } |
---|
1675 | | - |
---|
1676 | | - if (RTT_IS_STOPPED(rtt_status)) { |
---|
1677 | | - /* Ignore the Proxd event */ |
---|
1678 | | - return ret; |
---|
1679 | 3487 | } |
---|
1680 | 3488 | p_event = (wl_proxd_event_t *) event_data; |
---|
1681 | 3489 | version = ltoh16(p_event->version); |
---|
1682 | 3490 | if (version < WL_PROXD_API_VERSION) { |
---|
1683 | | - DHD_ERROR(("ignore non-ftm event version = 0x%0x < WL_PROXD_API_VERSION (0x%x)\n", |
---|
| 3491 | + DHD_RTT_ERR(("ignore non-ftm event version = 0x%0x < WL_PROXD_API_VERSION (0x%x)\n", |
---|
1684 | 3492 | version, WL_PROXD_API_VERSION)); |
---|
1685 | 3493 | return ret; |
---|
1686 | 3494 | } |
---|
1687 | | - if (!in_atomic()) { |
---|
1688 | | - mutex_lock(&rtt_status->rtt_mutex); |
---|
1689 | | - } |
---|
1690 | | - event_type = (wl_proxd_event_type_t) ltoh16(p_event->type); |
---|
1691 | 3495 | |
---|
1692 | | - kflags = in_softirq()? GFP_ATOMIC : GFP_KERNEL; |
---|
| 3496 | + event_type = (wl_proxd_event_type_t) ltoh16(p_event->type); |
---|
1693 | 3497 | |
---|
1694 | 3498 | DHD_RTT(("event_type=0x%x, ntoh16()=0x%x, ltoh16()=0x%x\n", |
---|
1695 | 3499 | p_event->type, ntoh16(p_event->type), ltoh16(p_event->type))); |
---|
1696 | 3500 | p_loginfo = ftm_get_event_type_loginfo(event_type); |
---|
1697 | 3501 | if (p_loginfo == NULL) { |
---|
1698 | | - DHD_ERROR(("receive an invalid FTM event %d\n", event_type)); |
---|
| 3502 | + DHD_RTT_ERR(("receive an invalid FTM event %d\n", event_type)); |
---|
1699 | 3503 | ret = -EINVAL; |
---|
1700 | | - goto exit; /* ignore this event */ |
---|
| 3504 | + return ret; /* ignore this event */ |
---|
1701 | 3505 | } |
---|
1702 | 3506 | /* get TLVs len, skip over event header */ |
---|
1703 | 3507 | if (ltoh16(p_event->len) < OFFSETOF(wl_proxd_event_t, tlvs)) { |
---|
1704 | | - DHD_ERROR(("invalid FTM event length:%d\n", ltoh16(p_event->len))); |
---|
| 3508 | + DHD_RTT_ERR(("invalid FTM event length:%d\n", ltoh16(p_event->len))); |
---|
1705 | 3509 | ret = -EINVAL; |
---|
1706 | | - goto exit; |
---|
| 3510 | + return ret; |
---|
1707 | 3511 | } |
---|
1708 | 3512 | tlvs_len = ltoh16(p_event->len) - OFFSETOF(wl_proxd_event_t, tlvs); |
---|
1709 | 3513 | DHD_RTT(("receive '%s' event: version=0x%x len=%d method=%d sid=%d tlvs_len=%d\n", |
---|
.. | .. |
---|
1713 | 3517 | ltoh16(p_event->method), |
---|
1714 | 3518 | ltoh16(p_event->sid), |
---|
1715 | 3519 | tlvs_len)); |
---|
1716 | | - rtt_target_info = &rtt_status->rtt_config.target_info[rtt_status->cur_idx]; |
---|
1717 | | - /* find a rtt_report_header for this mac address */ |
---|
1718 | | - list_for_each_entry(entry, &rtt_status->rtt_results_cache, list) { |
---|
1719 | | - if (!memcmp(&entry->peer_mac, &event->addr, ETHER_ADDR_LEN)) { |
---|
1720 | | - /* found a rtt_report_header for peer_mac in the list */ |
---|
1721 | | - is_new = FALSE; |
---|
1722 | | - rtt_results_header = entry; |
---|
1723 | | - break; |
---|
1724 | | - } |
---|
| 3520 | +#ifdef WL_CFG80211 |
---|
| 3521 | +#ifdef WL_NAN |
---|
| 3522 | + if ((event_type == WL_PROXD_EVENT_BURST_END) && |
---|
| 3523 | + dhd_rtt_is_nan_peer(dhd, &event->addr)) { |
---|
| 3524 | + DHD_RTT(("WL_PROXD_EVENT_BURST_END for NAN RTT\n")); |
---|
| 3525 | + ret = dhd_rtt_handle_nan_burst_end(dhd, &event->addr, p_event, tlvs_len); |
---|
| 3526 | + return ret; |
---|
1725 | 3527 | } |
---|
| 3528 | +#endif /* WL_NAN */ |
---|
1726 | 3529 | |
---|
| 3530 | + rtt_status = GET_RTTSTATE(dhd); |
---|
| 3531 | + NULL_CHECK(rtt_status, "rtt_status is NULL", ret); |
---|
| 3532 | + mutex_lock(&rtt_status->rtt_mutex); |
---|
| 3533 | + |
---|
| 3534 | + if (RTT_IS_STOPPED(rtt_status)) { |
---|
| 3535 | + /* Ignore the Proxd event */ |
---|
| 3536 | + DHD_RTT((" event handler rtt is stopped \n")); |
---|
| 3537 | + if (rtt_status->flags == WL_PROXD_SESSION_FLAG_TARGET) { |
---|
| 3538 | + DHD_RTT(("Device is target/Responder. Recv the event. \n")); |
---|
| 3539 | + } else { |
---|
| 3540 | + ret = BCME_NOTREADY; |
---|
| 3541 | + goto exit; |
---|
| 3542 | + } |
---|
| 3543 | + } |
---|
| 3544 | +#endif /* WL_CFG80211 */ |
---|
| 3545 | + |
---|
| 3546 | +#ifdef WL_CFG80211 |
---|
| 3547 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
| 3548 | + is_new = !dhd_rtt_get_report_header(rtt_status, |
---|
| 3549 | + &rtt_results_header, &event->addr); |
---|
| 3550 | + GCC_DIAGNOSTIC_POP(); |
---|
| 3551 | +#endif /* WL_CFG80211 */ |
---|
1727 | 3552 | switch (event_type) { |
---|
1728 | 3553 | case WL_PROXD_EVENT_SESSION_CREATE: |
---|
1729 | 3554 | DHD_RTT(("WL_PROXD_EVENT_SESSION_CREATE\n")); |
---|
.. | .. |
---|
1735 | 3560 | DHD_RTT(("WL_PROXD_EVENT_BURST_START\n")); |
---|
1736 | 3561 | break; |
---|
1737 | 3562 | case WL_PROXD_EVENT_BURST_END: |
---|
1738 | | - DHD_RTT(("WL_PROXD_EVENT_BURST_END\n")); |
---|
1739 | | - if (is_new) { |
---|
1740 | | - /* allocate new header for rtt_results */ |
---|
1741 | | - rtt_results_header = kzalloc(sizeof(rtt_results_header_t), kflags); |
---|
1742 | | - if (!rtt_results_header) { |
---|
1743 | | - ret = -ENOMEM; |
---|
1744 | | - goto exit; |
---|
1745 | | - } |
---|
1746 | | - /* Initialize the head of list for rtt result */ |
---|
1747 | | - INIT_LIST_HEAD(&rtt_results_header->result_list); |
---|
1748 | | - rtt_results_header->peer_mac = event->addr; |
---|
1749 | | - list_add_tail(&rtt_results_header->list, &rtt_status->rtt_results_cache); |
---|
| 3563 | + DHD_RTT(("WL_PROXD_EVENT_BURST_END for Legacy RTT\n")); |
---|
| 3564 | + /* allocate rtt_results for new legacy rtt results */ |
---|
| 3565 | + rtt_result = (rtt_result_t *)MALLOCZ(dhd->osh, sizeof(rtt_result_t)); |
---|
| 3566 | + if (!rtt_result) { |
---|
| 3567 | + ret = -ENOMEM; |
---|
| 3568 | + goto exit; |
---|
1750 | 3569 | } |
---|
1751 | | - if (tlvs_len > 0) { |
---|
1752 | | - /* allocate rtt_results for new results */ |
---|
1753 | | - rtt_result = kzalloc(sizeof(rtt_result_t), kflags); |
---|
1754 | | - if (!rtt_result) { |
---|
1755 | | - ret = -ENOMEM; |
---|
1756 | | - goto exit; |
---|
1757 | | - } |
---|
1758 | | - /* unpack TLVs and invokes the cbfn to print the event content TLVs */ |
---|
1759 | | - ret = bcm_unpack_xtlv_buf((void *) &(rtt_result->report), |
---|
1760 | | - (uint8 *)&p_event->tlvs[0], tlvs_len, |
---|
1761 | | - BCM_XTLV_OPTION_ALIGN32, rtt_unpack_xtlv_cbfn); |
---|
1762 | | - if (ret != BCME_OK) { |
---|
1763 | | - DHD_ERROR(("%s : Failed to unpack xtlv for an event\n", |
---|
1764 | | - __FUNCTION__)); |
---|
1765 | | - goto exit; |
---|
1766 | | - } |
---|
1767 | | - /* fill out the results from the configuration param */ |
---|
1768 | | - rtt_result->report.ftm_num = rtt_target_info->num_frames_per_burst; |
---|
1769 | | - rtt_result->report.type = RTT_TWO_WAY; |
---|
1770 | | - DHD_RTT(("report->ftm_num : %d\n", rtt_result->report.ftm_num)); |
---|
1771 | | - rtt_result->report_len = RTT_REPORT_SIZE; |
---|
1772 | | - |
---|
1773 | | - list_add_tail(&rtt_result->list, &rtt_results_header->result_list); |
---|
1774 | | - rtt_results_header->result_cnt++; |
---|
1775 | | - rtt_results_header->result_tot_len += rtt_result->report_len; |
---|
| 3570 | + ret = dhd_rtt_handle_directed_rtt_burst_end(dhd, &event->addr, |
---|
| 3571 | + p_event, tlvs_len, rtt_result, FALSE); |
---|
| 3572 | + if (rtt_result && (ret != BCME_OK)) { |
---|
| 3573 | + kfree(rtt_result); |
---|
| 3574 | + rtt_result = NULL; |
---|
| 3575 | + goto exit; |
---|
1776 | 3576 | } |
---|
1777 | 3577 | break; |
---|
1778 | 3578 | case WL_PROXD_EVENT_SESSION_END: |
---|
1779 | | - DHD_RTT(("WL_PROXD_EVENT_SESSION_END\n")); |
---|
| 3579 | + DHD_RTT(("WL_PROXD_EVENT_SESSION_END\n")); |
---|
| 3580 | + if (dhd_rtt_is_nan_peer(dhd, &event->addr)) { |
---|
| 3581 | + /* |
---|
| 3582 | + * Nothing to do for session end for nan peer |
---|
| 3583 | + * All taken care in burst end and nan rng rep |
---|
| 3584 | + */ |
---|
| 3585 | + break; |
---|
| 3586 | + } |
---|
| 3587 | +#ifdef WL_CFG80211 |
---|
1780 | 3588 | if (!RTT_IS_ENABLED(rtt_status)) { |
---|
1781 | 3589 | DHD_RTT(("Ignore the session end evt\n")); |
---|
1782 | 3590 | goto exit; |
---|
1783 | 3591 | } |
---|
| 3592 | +#endif /* WL_CFG80211 */ |
---|
1784 | 3593 | if (tlvs_len > 0) { |
---|
1785 | 3594 | /* unpack TLVs and invokes the cbfn to print the event content TLVs */ |
---|
1786 | 3595 | ret = bcm_unpack_xtlv_buf((void *) &session_status, |
---|
1787 | 3596 | (uint8 *)&p_event->tlvs[0], tlvs_len, |
---|
1788 | 3597 | BCM_XTLV_OPTION_ALIGN32, rtt_unpack_xtlv_cbfn); |
---|
1789 | 3598 | if (ret != BCME_OK) { |
---|
1790 | | - DHD_ERROR(("%s : Failed to unpack xtlv for an event\n", |
---|
| 3599 | + DHD_RTT_ERR(("%s : Failed to unpack xtlv for an event\n", |
---|
1791 | 3600 | __FUNCTION__)); |
---|
1792 | 3601 | goto exit; |
---|
1793 | 3602 | } |
---|
1794 | 3603 | } |
---|
| 3604 | +#ifdef WL_CFG80211 |
---|
1795 | 3605 | /* In case of no result for the peer device, make fake result for error case */ |
---|
1796 | 3606 | if (is_new) { |
---|
1797 | | - /* allocate new header for rtt_results */ |
---|
1798 | | - rtt_results_header = kzalloc(sizeof(rtt_results_header_t), GFP_KERNEL); |
---|
1799 | | - if (!rtt_results_header) { |
---|
1800 | | - ret = -ENOMEM; |
---|
1801 | | - goto exit; |
---|
1802 | | - } |
---|
1803 | | - /* Initialize the head of list for rtt result */ |
---|
1804 | | - INIT_LIST_HEAD(&rtt_results_header->result_list); |
---|
1805 | | - rtt_results_header->peer_mac = event->addr; |
---|
1806 | | - list_add_tail(&rtt_results_header->list, &rtt_status->rtt_results_cache); |
---|
1807 | | - |
---|
1808 | | - /* allocate rtt_results for new results */ |
---|
1809 | | - rtt_result = kzalloc(sizeof(rtt_result_t), kflags); |
---|
1810 | | - if (!rtt_result) { |
---|
1811 | | - ret = -ENOMEM; |
---|
1812 | | - kfree(rtt_results_header); |
---|
1813 | | - goto exit; |
---|
1814 | | - } |
---|
1815 | | - /* fill out the results from the configuration param */ |
---|
1816 | | - rtt_result->report.ftm_num = rtt_target_info->num_frames_per_burst; |
---|
1817 | | - rtt_result->report.type = RTT_TWO_WAY; |
---|
1818 | | - DHD_RTT(("report->ftm_num : %d\n", rtt_result->report.ftm_num)); |
---|
1819 | | - rtt_result->report_len = RTT_REPORT_SIZE; |
---|
1820 | | - rtt_result->report.status = RTT_REASON_FAIL_NO_RSP; |
---|
1821 | | - rtt_result->report.addr = rtt_target_info->addr; |
---|
1822 | | - rtt_result->report.distance = FTM_INVALID; |
---|
1823 | | - list_add_tail(&rtt_result->list, &rtt_results_header->result_list); |
---|
1824 | | - rtt_results_header->result_cnt++; |
---|
1825 | | - rtt_results_header->result_tot_len += rtt_result->report_len; |
---|
| 3607 | + dhd_rtt_create_failure_result(rtt_status, &event->addr); |
---|
1826 | 3608 | } |
---|
1827 | | - /* find next target to trigger RTT */ |
---|
1828 | | - for (idx = (rtt_status->cur_idx + 1); |
---|
1829 | | - idx < rtt_status->rtt_config.rtt_target_cnt; idx++) { |
---|
1830 | | - /* skip the disabled device */ |
---|
1831 | | - if (rtt_status->rtt_config.target_info[idx].disable) { |
---|
1832 | | - continue; |
---|
1833 | | - } else { |
---|
1834 | | - /* set the idx to cur_idx */ |
---|
1835 | | - rtt_status->cur_idx = idx; |
---|
1836 | | - break; |
---|
1837 | | - } |
---|
1838 | | - } |
---|
1839 | | - if (idx < rtt_status->rtt_config.rtt_target_cnt) { |
---|
1840 | | - /* restart to measure RTT from next device */ |
---|
1841 | | - schedule_work(&rtt_status->work); |
---|
1842 | | - } else { |
---|
1843 | | - DHD_RTT(("RTT_STOPPED\n")); |
---|
1844 | | - rtt_status->status = RTT_STOPPED; |
---|
1845 | | - /* to turn on mpc mode */ |
---|
1846 | | - schedule_work(&rtt_status->work); |
---|
1847 | | - /* notify the completed information to others */ |
---|
1848 | | - list_for_each_entry(iter, &rtt_status->noti_fn_list, list) { |
---|
1849 | | - iter->noti_fn(iter->ctx, &rtt_status->rtt_results_cache); |
---|
1850 | | - } |
---|
1851 | | - /* remove the rtt results in cache */ |
---|
1852 | | - if (!list_empty(&rtt_status->rtt_results_cache)) { |
---|
1853 | | - /* Iterate rtt_results_header list */ |
---|
1854 | | - list_for_each_entry_safe(entry, next, |
---|
1855 | | - &rtt_status->rtt_results_cache, list) { |
---|
1856 | | - list_del(&entry->list); |
---|
1857 | | - /* Iterate rtt_result list */ |
---|
1858 | | - list_for_each_entry_safe(rtt_result, next2, |
---|
1859 | | - &entry->result_list, list) { |
---|
1860 | | - list_del(&rtt_result->list); |
---|
1861 | | - kfree(rtt_result); |
---|
1862 | | - } |
---|
1863 | | - kfree(entry); |
---|
1864 | | - } |
---|
1865 | | - } |
---|
1866 | | - |
---|
1867 | | - /* reinitialize the HEAD */ |
---|
1868 | | - INIT_LIST_HEAD(&rtt_status->rtt_results_cache); |
---|
1869 | | - /* clear information for rtt_config */ |
---|
1870 | | - rtt_status->rtt_config.rtt_target_cnt = 0; |
---|
1871 | | - memset(rtt_status->rtt_config.target_info, 0, |
---|
1872 | | - TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT)); |
---|
1873 | | - rtt_status->cur_idx = 0; |
---|
1874 | | - } |
---|
| 3609 | + DHD_RTT(("\n Not Nan peer..proceed to notify result and restart\n")); |
---|
| 3610 | + dhd_rtt_handle_rtt_session_end(dhd); |
---|
| 3611 | +#endif /* WL_CFG80211 */ |
---|
1875 | 3612 | break; |
---|
1876 | 3613 | case WL_PROXD_EVENT_SESSION_RESTART: |
---|
1877 | 3614 | DHD_RTT(("WL_PROXD_EVENT_SESSION_RESTART\n")); |
---|
.. | .. |
---|
1894 | 3631 | case WL_PROXD_EVENT_RANGING: |
---|
1895 | 3632 | DHD_RTT(("WL_PROXD_EVENT_RANGING\n")); |
---|
1896 | 3633 | break; |
---|
| 3634 | + case WL_PROXD_EVENT_COLLECT: |
---|
| 3635 | + DHD_RTT(("WL_PROXD_EVENT_COLLECT\n")); |
---|
| 3636 | + if (tlvs_len > 0) { |
---|
| 3637 | + void *buffer = NULL; |
---|
| 3638 | + if (!(buffer = (void *)MALLOCZ(dhd->osh, tlvs_len))) { |
---|
| 3639 | + ret = -ENOMEM; |
---|
| 3640 | + goto exit; |
---|
| 3641 | + } |
---|
| 3642 | + /* unpack TLVs and invokes the cbfn to print the event content TLVs */ |
---|
| 3643 | + ret = bcm_unpack_xtlv_buf(buffer, |
---|
| 3644 | + (uint8 *)&p_event->tlvs[0], tlvs_len, |
---|
| 3645 | + BCM_XTLV_OPTION_NONE, rtt_unpack_xtlv_cbfn); |
---|
| 3646 | + kfree(buffer); |
---|
| 3647 | + if (ret != BCME_OK) { |
---|
| 3648 | + DHD_RTT_ERR(("%s : Failed to unpack xtlv for event %d\n", |
---|
| 3649 | + __FUNCTION__, event_type)); |
---|
| 3650 | + goto exit; |
---|
| 3651 | + } |
---|
| 3652 | + } |
---|
| 3653 | + break; |
---|
| 3654 | + case WL_PROXD_EVENT_MF_STATS: |
---|
| 3655 | + DHD_RTT(("WL_PROXD_EVENT_MF_STATS\n")); |
---|
| 3656 | + if (tlvs_len > 0) { |
---|
| 3657 | + void *buffer = NULL; |
---|
| 3658 | + if (!(buffer = (void *)MALLOCZ(dhd->osh, tlvs_len))) { |
---|
| 3659 | + ret = -ENOMEM; |
---|
| 3660 | + goto exit; |
---|
| 3661 | + } |
---|
| 3662 | + /* unpack TLVs and invokes the cbfn to print the event content TLVs */ |
---|
| 3663 | + ret = bcm_unpack_xtlv_buf(buffer, |
---|
| 3664 | + (uint8 *)&p_event->tlvs[0], tlvs_len, |
---|
| 3665 | + BCM_XTLV_OPTION_NONE, rtt_unpack_xtlv_cbfn); |
---|
| 3666 | + kfree(buffer); |
---|
| 3667 | + if (ret != BCME_OK) { |
---|
| 3668 | + DHD_RTT_ERR(("%s : Failed to unpack xtlv for event %d\n", |
---|
| 3669 | + __FUNCTION__, event_type)); |
---|
| 3670 | + goto exit; |
---|
| 3671 | + } |
---|
| 3672 | + } |
---|
| 3673 | + break; |
---|
1897 | 3674 | |
---|
1898 | 3675 | default: |
---|
1899 | | - DHD_ERROR(("WLC_E_PROXD: not supported EVENT Type:%d\n", event_type)); |
---|
| 3676 | + DHD_RTT_ERR(("WLC_E_PROXD: not supported EVENT Type:%d\n", event_type)); |
---|
1900 | 3677 | break; |
---|
1901 | 3678 | } |
---|
1902 | 3679 | exit: |
---|
1903 | | - if (!in_atomic()) { |
---|
1904 | | - mutex_unlock(&rtt_status->rtt_mutex); |
---|
1905 | | - } |
---|
| 3680 | +#ifdef WL_CFG80211 |
---|
| 3681 | + mutex_unlock(&rtt_status->rtt_mutex); |
---|
| 3682 | +#endif /* WL_CFG80211 */ |
---|
1906 | 3683 | |
---|
1907 | 3684 | return ret; |
---|
1908 | 3685 | } |
---|
1909 | 3686 | |
---|
| 3687 | +#ifdef WL_CFG80211 |
---|
1910 | 3688 | static void |
---|
1911 | 3689 | dhd_rtt_work(struct work_struct *work) |
---|
1912 | 3690 | { |
---|
1913 | 3691 | rtt_status_info_t *rtt_status; |
---|
1914 | 3692 | dhd_pub_t *dhd; |
---|
| 3693 | + |
---|
| 3694 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
1915 | 3695 | rtt_status = container_of(work, rtt_status_info_t, work); |
---|
1916 | | - if (rtt_status == NULL) { |
---|
1917 | | - DHD_ERROR(("%s : rtt_status is NULL\n", __FUNCTION__)); |
---|
1918 | | - return; |
---|
1919 | | - } |
---|
| 3696 | + GCC_DIAGNOSTIC_POP(); |
---|
| 3697 | + |
---|
1920 | 3698 | dhd = rtt_status->dhd; |
---|
1921 | 3699 | if (dhd == NULL) { |
---|
1922 | | - DHD_ERROR(("%s : dhd is NULL\n", __FUNCTION__)); |
---|
| 3700 | + DHD_RTT_ERR(("%s : dhd is NULL\n", __FUNCTION__)); |
---|
1923 | 3701 | return; |
---|
1924 | 3702 | } |
---|
1925 | 3703 | (void) dhd_rtt_start(dhd); |
---|
1926 | 3704 | } |
---|
| 3705 | +#endif /* WL_CFG80211 */ |
---|
1927 | 3706 | |
---|
1928 | 3707 | int |
---|
1929 | 3708 | dhd_rtt_capability(dhd_pub_t *dhd, rtt_capabilities_t *capa) |
---|
.. | .. |
---|
1935 | 3714 | NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
1936 | 3715 | NULL_CHECK(capa, "capa is NULL", err); |
---|
1937 | 3716 | bzero(capa, sizeof(rtt_capabilities_t)); |
---|
1938 | | - switch (rtt_status->rtt_capa.proto) { |
---|
1939 | | - case RTT_CAP_ONE_WAY: |
---|
1940 | | - capa->rtt_one_sided_supported = 1; |
---|
1941 | | - break; |
---|
1942 | | - case RTT_CAP_FTM_WAY: |
---|
1943 | | - capa->rtt_ftm_supported = 1; |
---|
1944 | | - break; |
---|
1945 | | - } |
---|
1946 | 3717 | |
---|
1947 | | - switch (rtt_status->rtt_capa.feature) { |
---|
1948 | | - case RTT_FEATURE_LCI: |
---|
| 3718 | + /* set rtt capabilities */ |
---|
| 3719 | + if (rtt_status->rtt_capa.proto & RTT_CAP_ONE_WAY) |
---|
| 3720 | + capa->rtt_one_sided_supported = 1; |
---|
| 3721 | + if (rtt_status->rtt_capa.proto & RTT_CAP_FTM_WAY) |
---|
| 3722 | + capa->rtt_ftm_supported = 1; |
---|
| 3723 | + |
---|
| 3724 | + if (rtt_status->rtt_capa.feature & RTT_FEATURE_LCI) |
---|
1949 | 3725 | capa->lci_support = 1; |
---|
1950 | | - break; |
---|
1951 | | - case RTT_FEATURE_LCR: |
---|
| 3726 | + if (rtt_status->rtt_capa.feature & RTT_FEATURE_LCR) |
---|
1952 | 3727 | capa->lcr_support = 1; |
---|
1953 | | - break; |
---|
1954 | | - case RTT_FEATURE_PREAMBLE: |
---|
| 3728 | + if (rtt_status->rtt_capa.feature & RTT_FEATURE_PREAMBLE) |
---|
1955 | 3729 | capa->preamble_support = 1; |
---|
1956 | | - break; |
---|
1957 | | - case RTT_FEATURE_BW: |
---|
| 3730 | + if (rtt_status->rtt_capa.feature & RTT_FEATURE_BW) |
---|
1958 | 3731 | capa->bw_support = 1; |
---|
1959 | | - break; |
---|
1960 | | - } |
---|
| 3732 | + |
---|
1961 | 3733 | /* bit mask */ |
---|
1962 | 3734 | capa->preamble_support = rtt_status->rtt_capa.preamble; |
---|
1963 | 3735 | capa->bw_support = rtt_status->rtt_capa.bw; |
---|
.. | .. |
---|
1965 | 3737 | return err; |
---|
1966 | 3738 | } |
---|
1967 | 3739 | |
---|
| 3740 | +#ifdef WL_CFG80211 |
---|
| 3741 | +int |
---|
| 3742 | +dhd_rtt_avail_channel(dhd_pub_t *dhd, wifi_channel_info *channel_info) |
---|
| 3743 | +{ |
---|
| 3744 | + u32 chanspec = 0; |
---|
| 3745 | + int err = BCME_OK; |
---|
| 3746 | + chanspec_t c = 0; |
---|
| 3747 | + u32 channel; |
---|
| 3748 | + struct net_device *dev = dhd_linux_get_primary_netdev(dhd); |
---|
| 3749 | + |
---|
| 3750 | + if ((err = wldev_iovar_getint(dev, "chanspec", |
---|
| 3751 | + (s32 *)&chanspec)) == BCME_OK) { |
---|
| 3752 | + c = (chanspec_t)dtoh32(chanspec); |
---|
| 3753 | + c = wl_chspec_driver_to_host(c); |
---|
| 3754 | + channel = wf_chspec_ctlchan(c); |
---|
| 3755 | + DHD_RTT((" control channel is %d \n", channel)); |
---|
| 3756 | + if (CHSPEC_IS20(c)) { |
---|
| 3757 | + channel_info->width = WIFI_CHAN_WIDTH_20; |
---|
| 3758 | + DHD_RTT((" band is 20 \n")); |
---|
| 3759 | + } else if (CHSPEC_IS40(c)) { |
---|
| 3760 | + channel_info->width = WIFI_CHAN_WIDTH_40; |
---|
| 3761 | + DHD_RTT(("band is 40 \n")); |
---|
| 3762 | + } else { |
---|
| 3763 | + channel_info->width = WIFI_CHAN_WIDTH_80; |
---|
| 3764 | + DHD_RTT(("band is 80 \n")); |
---|
| 3765 | + } |
---|
| 3766 | + if (CHSPEC_IS2G(c) && (channel >= CH_MIN_2G_CHANNEL) && |
---|
| 3767 | + (channel <= CH_MAX_2G_CHANNEL)) { |
---|
| 3768 | + channel_info->center_freq = |
---|
| 3769 | + ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); |
---|
| 3770 | + } else if (CHSPEC_IS5G(c) && channel >= CH_MIN_5G_CHANNEL) { |
---|
| 3771 | + channel_info->center_freq = |
---|
| 3772 | + ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); |
---|
| 3773 | + } |
---|
| 3774 | + if ((channel_info->width == WIFI_CHAN_WIDTH_80) || |
---|
| 3775 | + (channel_info->width == WIFI_CHAN_WIDTH_40)) { |
---|
| 3776 | + channel = CHSPEC_CHANNEL(c); |
---|
| 3777 | + channel_info->center_freq0 = |
---|
| 3778 | + ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); |
---|
| 3779 | + } |
---|
| 3780 | + } else { |
---|
| 3781 | + DHD_RTT_ERR(("Failed to get the chanspec \n")); |
---|
| 3782 | + } |
---|
| 3783 | + return err; |
---|
| 3784 | +} |
---|
| 3785 | + |
---|
| 3786 | +int |
---|
| 3787 | +dhd_rtt_enable_responder(dhd_pub_t *dhd, wifi_channel_info *channel_info) |
---|
| 3788 | +{ |
---|
| 3789 | + int err = BCME_OK; |
---|
| 3790 | + char chanbuf[CHANSPEC_STR_LEN]; |
---|
| 3791 | + int pm = PM_OFF; |
---|
| 3792 | + int ftm_cfg_cnt = 0; |
---|
| 3793 | + chanspec_t chanspec; |
---|
| 3794 | + wifi_channel_info_t channel; |
---|
| 3795 | + struct net_device *dev = dhd_linux_get_primary_netdev(dhd); |
---|
| 3796 | + ftm_config_options_info_t ftm_configs[FTM_MAX_CONFIGS]; |
---|
| 3797 | + ftm_config_param_info_t ftm_params[FTM_MAX_PARAMS]; |
---|
| 3798 | + rtt_status_info_t *rtt_status; |
---|
| 3799 | + |
---|
| 3800 | + memset(&channel, 0, sizeof(channel)); |
---|
| 3801 | + BCM_REFERENCE(chanbuf); |
---|
| 3802 | + NULL_CHECK(dhd, "dhd is NULL", err); |
---|
| 3803 | + rtt_status = GET_RTTSTATE(dhd); |
---|
| 3804 | + NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
| 3805 | + if (RTT_IS_STOPPED(rtt_status)) { |
---|
| 3806 | + DHD_RTT(("STA responder/Target. \n")); |
---|
| 3807 | + } |
---|
| 3808 | + DHD_RTT(("Enter %s \n", __FUNCTION__)); |
---|
| 3809 | + if (!dhd_is_associated(dhd, 0, NULL)) { |
---|
| 3810 | + if (channel_info) { |
---|
| 3811 | + channel.width = channel_info->width; |
---|
| 3812 | + channel.center_freq = channel_info->center_freq; |
---|
| 3813 | + channel.center_freq0 = channel_info->center_freq; |
---|
| 3814 | + } |
---|
| 3815 | + else { |
---|
| 3816 | + channel.width = WIFI_CHAN_WIDTH_80; |
---|
| 3817 | + channel.center_freq = DEFAULT_FTM_FREQ; |
---|
| 3818 | + channel.center_freq0 = DEFAULT_FTM_CNTR_FREQ0; |
---|
| 3819 | + } |
---|
| 3820 | + chanspec = dhd_rtt_convert_to_chspec(channel); |
---|
| 3821 | + DHD_RTT(("chanspec/channel set as %s for rtt.\n", |
---|
| 3822 | + wf_chspec_ntoa(chanspec, chanbuf))); |
---|
| 3823 | + err = wldev_iovar_setint(dev, "chanspec", chanspec); |
---|
| 3824 | + if (err) { |
---|
| 3825 | + DHD_RTT_ERR(("Failed to set the chanspec \n")); |
---|
| 3826 | + } |
---|
| 3827 | + } |
---|
| 3828 | + rtt_status->pm = PM_OFF; |
---|
| 3829 | + err = wldev_ioctl_get(dev, WLC_GET_PM, &rtt_status->pm, sizeof(rtt_status->pm)); |
---|
| 3830 | + DHD_RTT(("Current PM value read %d\n", rtt_status->pm)); |
---|
| 3831 | + if (err) { |
---|
| 3832 | + DHD_RTT_ERR(("Failed to get the PM value \n")); |
---|
| 3833 | + } else { |
---|
| 3834 | + err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm)); |
---|
| 3835 | + if (err) { |
---|
| 3836 | + DHD_RTT_ERR(("Failed to set the PM \n")); |
---|
| 3837 | + rtt_status->pm_restore = FALSE; |
---|
| 3838 | + } else { |
---|
| 3839 | + rtt_status->pm_restore = TRUE; |
---|
| 3840 | + } |
---|
| 3841 | + } |
---|
| 3842 | + if (!RTT_IS_ENABLED(rtt_status)) { |
---|
| 3843 | + err = dhd_rtt_ftm_enable(dhd, TRUE); |
---|
| 3844 | + if (err) { |
---|
| 3845 | + DHD_RTT_ERR(("Failed to enable FTM (%d)\n", err)); |
---|
| 3846 | + goto exit; |
---|
| 3847 | + } |
---|
| 3848 | + DHD_RTT(("FTM enabled \n")); |
---|
| 3849 | + } |
---|
| 3850 | + rtt_status->status = RTT_ENABLED; |
---|
| 3851 | + DHD_RTT(("Responder enabled \n")); |
---|
| 3852 | + memset(ftm_configs, 0, sizeof(ftm_configs)); |
---|
| 3853 | + memset(ftm_params, 0, sizeof(ftm_params)); |
---|
| 3854 | + ftm_configs[ftm_cfg_cnt].enable = TRUE; |
---|
| 3855 | + ftm_configs[ftm_cfg_cnt++].flags = WL_PROXD_SESSION_FLAG_TARGET; |
---|
| 3856 | + rtt_status->flags = WL_PROXD_SESSION_FLAG_TARGET; |
---|
| 3857 | + DHD_RTT(("Set the device as responder \n")); |
---|
| 3858 | + err = dhd_rtt_ftm_config(dhd, FTM_DEFAULT_SESSION, FTM_CONFIG_CAT_OPTIONS, |
---|
| 3859 | + ftm_configs, ftm_cfg_cnt); |
---|
| 3860 | +exit: |
---|
| 3861 | + if (err) { |
---|
| 3862 | + rtt_status->status = RTT_STOPPED; |
---|
| 3863 | + DHD_RTT_ERR(("rtt is stopped %s \n", __FUNCTION__)); |
---|
| 3864 | + dhd_rtt_ftm_enable(dhd, FALSE); |
---|
| 3865 | + DHD_RTT(("restoring the PM value \n")); |
---|
| 3866 | + if (rtt_status->pm_restore) { |
---|
| 3867 | + pm = PM_FAST; |
---|
| 3868 | + err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm)); |
---|
| 3869 | + if (err) { |
---|
| 3870 | + DHD_RTT_ERR(("Failed to restore PM \n")); |
---|
| 3871 | + } else { |
---|
| 3872 | + rtt_status->pm_restore = FALSE; |
---|
| 3873 | + } |
---|
| 3874 | + } |
---|
| 3875 | + } |
---|
| 3876 | + return err; |
---|
| 3877 | +} |
---|
| 3878 | + |
---|
| 3879 | +int |
---|
| 3880 | +dhd_rtt_cancel_responder(dhd_pub_t *dhd) |
---|
| 3881 | +{ |
---|
| 3882 | + int err = BCME_OK; |
---|
| 3883 | + rtt_status_info_t *rtt_status; |
---|
| 3884 | + int pm = 0; |
---|
| 3885 | + struct net_device *dev = dhd_linux_get_primary_netdev(dhd); |
---|
| 3886 | + |
---|
| 3887 | + NULL_CHECK(dhd, "dhd is NULL", err); |
---|
| 3888 | + rtt_status = GET_RTTSTATE(dhd); |
---|
| 3889 | + NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
| 3890 | + DHD_RTT(("Enter %s \n", __FUNCTION__)); |
---|
| 3891 | + err = dhd_rtt_ftm_enable(dhd, FALSE); |
---|
| 3892 | + if (err) { |
---|
| 3893 | + DHD_RTT_ERR(("failed to disable FTM (%d)\n", err)); |
---|
| 3894 | + } |
---|
| 3895 | + rtt_status->status = RTT_STOPPED; |
---|
| 3896 | + if (rtt_status->pm_restore) { |
---|
| 3897 | + pm = PM_FAST; |
---|
| 3898 | + DHD_RTT(("pm_restore =%d \n", rtt_status->pm_restore)); |
---|
| 3899 | + err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm)); |
---|
| 3900 | + if (err) { |
---|
| 3901 | + DHD_RTT_ERR(("Failed to restore PM \n")); |
---|
| 3902 | + } else { |
---|
| 3903 | + rtt_status->pm_restore = FALSE; |
---|
| 3904 | + } |
---|
| 3905 | + } |
---|
| 3906 | + return err; |
---|
| 3907 | +} |
---|
| 3908 | +#endif /* WL_CFG80211 */ |
---|
| 3909 | + |
---|
1968 | 3910 | int |
---|
1969 | 3911 | dhd_rtt_init(dhd_pub_t *dhd) |
---|
1970 | 3912 | { |
---|
1971 | | - int err = BCME_OK, ret; |
---|
1972 | | - int32 up = 1; |
---|
| 3913 | + int err = BCME_OK; |
---|
| 3914 | +#ifdef WL_CFG80211 |
---|
| 3915 | + int ret; |
---|
| 3916 | + int32 drv_up = 1; |
---|
1973 | 3917 | int32 version; |
---|
1974 | 3918 | rtt_status_info_t *rtt_status; |
---|
| 3919 | + ftm_config_param_info_t ftm_params[FTM_MAX_PARAMS]; |
---|
| 3920 | + int ftm_param_cnt = 0; |
---|
| 3921 | + |
---|
1975 | 3922 | NULL_CHECK(dhd, "dhd is NULL", err); |
---|
1976 | 3923 | if (dhd->rtt_state) { |
---|
1977 | 3924 | return err; |
---|
1978 | 3925 | } |
---|
1979 | | - dhd->rtt_state = kzalloc(sizeof(rtt_status_info_t), GFP_KERNEL); |
---|
| 3926 | + dhd->rtt_state = (rtt_status_info_t *)MALLOCZ(dhd->osh, |
---|
| 3927 | + sizeof(rtt_status_info_t)); |
---|
1980 | 3928 | if (dhd->rtt_state == NULL) { |
---|
1981 | 3929 | err = BCME_NOMEM; |
---|
1982 | | - DHD_ERROR(("%s : failed to create rtt_state\n", __FUNCTION__)); |
---|
| 3930 | + DHD_RTT_ERR(("%s : failed to create rtt_state\n", __FUNCTION__)); |
---|
1983 | 3931 | return err; |
---|
1984 | 3932 | } |
---|
1985 | 3933 | bzero(dhd->rtt_state, sizeof(rtt_status_info_t)); |
---|
1986 | 3934 | rtt_status = GET_RTTSTATE(dhd); |
---|
1987 | 3935 | rtt_status->rtt_config.target_info = |
---|
1988 | | - kzalloc(TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT), GFP_KERNEL); |
---|
| 3936 | + (rtt_target_info_t *)MALLOCZ(dhd->osh, |
---|
| 3937 | + TARGET_INFO_SIZE(RTT_MAX_TARGET_CNT)); |
---|
1989 | 3938 | if (rtt_status->rtt_config.target_info == NULL) { |
---|
1990 | | - DHD_ERROR(("%s failed to allocate the target info for %d\n", |
---|
| 3939 | + DHD_RTT_ERR(("%s failed to allocate the target info for %d\n", |
---|
1991 | 3940 | __FUNCTION__, RTT_MAX_TARGET_CNT)); |
---|
1992 | 3941 | err = BCME_NOMEM; |
---|
1993 | 3942 | goto exit; |
---|
1994 | 3943 | } |
---|
1995 | 3944 | rtt_status->dhd = dhd; |
---|
1996 | 3945 | /* need to do WLC_UP */ |
---|
1997 | | - dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&up, sizeof(int32), TRUE, 0); |
---|
| 3946 | + dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&drv_up, sizeof(int32), TRUE, 0); |
---|
1998 | 3947 | |
---|
1999 | 3948 | ret = dhd_rtt_get_version(dhd, &version); |
---|
2000 | 3949 | if (ret == BCME_OK && (version == WL_PROXD_API_VERSION)) { |
---|
2001 | | - DHD_ERROR(("%s : FTM is supported\n", __FUNCTION__)); |
---|
| 3950 | + DHD_RTT_ERR(("%s : FTM is supported\n", __FUNCTION__)); |
---|
2002 | 3951 | /* rtt_status->rtt_capa.proto |= RTT_CAP_ONE_WAY; */ |
---|
2003 | 3952 | rtt_status->rtt_capa.proto |= RTT_CAP_FTM_WAY; |
---|
2004 | 3953 | |
---|
2005 | 3954 | /* indicate to set tx rate */ |
---|
| 3955 | + rtt_status->rtt_capa.feature |= RTT_FEATURE_LCI; |
---|
| 3956 | + rtt_status->rtt_capa.feature |= RTT_FEATURE_LCR; |
---|
2006 | 3957 | rtt_status->rtt_capa.feature |= RTT_FEATURE_PREAMBLE; |
---|
2007 | 3958 | rtt_status->rtt_capa.preamble |= RTT_PREAMBLE_VHT; |
---|
2008 | 3959 | rtt_status->rtt_capa.preamble |= RTT_PREAMBLE_HT; |
---|
.. | .. |
---|
2014 | 3965 | rtt_status->rtt_capa.bw |= RTT_BW_80; |
---|
2015 | 3966 | } else { |
---|
2016 | 3967 | if ((ret != BCME_OK) || (version == 0)) { |
---|
2017 | | - DHD_ERROR(("%s : FTM is not supported\n", __FUNCTION__)); |
---|
| 3968 | + DHD_RTT_ERR(("%s : FTM is not supported\n", __FUNCTION__)); |
---|
2018 | 3969 | } else { |
---|
2019 | | - DHD_ERROR(("%s : FTM version mismatch between HOST (%d) and FW (%d)\n", |
---|
| 3970 | + DHD_RTT_ERR(("%s : FTM version mismatch between HOST (%d) and FW (%d)\n", |
---|
2020 | 3971 | __FUNCTION__, WL_PROXD_API_VERSION, version)); |
---|
2021 | 3972 | } |
---|
2022 | 3973 | } |
---|
2023 | 3974 | /* cancel all of RTT request once we got the cancel request */ |
---|
2024 | 3975 | rtt_status->all_cancel = TRUE; |
---|
2025 | 3976 | mutex_init(&rtt_status->rtt_mutex); |
---|
| 3977 | + mutex_init(&rtt_status->geofence_mutex); |
---|
2026 | 3978 | INIT_LIST_HEAD(&rtt_status->noti_fn_list); |
---|
2027 | 3979 | INIT_LIST_HEAD(&rtt_status->rtt_results_cache); |
---|
2028 | 3980 | INIT_WORK(&rtt_status->work, dhd_rtt_work); |
---|
| 3981 | + /* initialize proxd timer */ |
---|
| 3982 | + INIT_DELAYED_WORK(&rtt_status->proxd_timeout, dhd_rtt_timeout_work); |
---|
| 3983 | +#ifdef WL_NAN |
---|
| 3984 | + /* initialize proxd retry timer */ |
---|
| 3985 | + INIT_DELAYED_WORK(&rtt_status->rtt_retry_timer, dhd_rtt_retry_work); |
---|
| 3986 | + /* initialize non zero params of geofenne cfg */ |
---|
| 3987 | + rtt_status->geofence_cfg.cur_target_idx = DHD_RTT_INVALID_TARGET_INDEX; |
---|
| 3988 | +#endif /* WL_NAN */ |
---|
| 3989 | + /* Global proxd config */ |
---|
| 3990 | + ftm_params[ftm_param_cnt].event_mask = ((1 << WL_PROXD_EVENT_BURST_END) | |
---|
| 3991 | + (1 << WL_PROXD_EVENT_SESSION_END)); |
---|
| 3992 | + ftm_params[ftm_param_cnt++].tlvid = WL_PROXD_TLV_ID_EVENT_MASK; |
---|
| 3993 | + dhd_rtt_ftm_config(dhd, 0, FTM_CONFIG_CAT_GENERAL, |
---|
| 3994 | + ftm_params, ftm_param_cnt); |
---|
2029 | 3995 | exit: |
---|
2030 | 3996 | if (err < 0) { |
---|
2031 | 3997 | kfree(rtt_status->rtt_config.target_info); |
---|
2032 | 3998 | kfree(dhd->rtt_state); |
---|
2033 | 3999 | } |
---|
| 4000 | +#endif /* WL_CFG80211 */ |
---|
2034 | 4001 | return err; |
---|
| 4002 | + |
---|
2035 | 4003 | } |
---|
2036 | 4004 | |
---|
2037 | 4005 | int |
---|
2038 | 4006 | dhd_rtt_deinit(dhd_pub_t *dhd) |
---|
2039 | 4007 | { |
---|
2040 | 4008 | int err = BCME_OK; |
---|
| 4009 | +#ifdef WL_CFG80211 |
---|
2041 | 4010 | rtt_status_info_t *rtt_status; |
---|
2042 | 4011 | rtt_results_header_t *rtt_header, *next; |
---|
2043 | 4012 | rtt_result_t *rtt_result, *next2; |
---|
.. | .. |
---|
2046 | 4015 | rtt_status = GET_RTTSTATE(dhd); |
---|
2047 | 4016 | NULL_CHECK(rtt_status, "rtt_status is NULL", err); |
---|
2048 | 4017 | rtt_status->status = RTT_STOPPED; |
---|
| 4018 | + DHD_RTT(("rtt is stopped %s \n", __FUNCTION__)); |
---|
2049 | 4019 | /* clear evt callback list */ |
---|
| 4020 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
2050 | 4021 | if (!list_empty(&rtt_status->noti_fn_list)) { |
---|
2051 | 4022 | list_for_each_entry_safe(iter, iter2, &rtt_status->noti_fn_list, list) { |
---|
2052 | 4023 | list_del(&iter->list); |
---|
.. | .. |
---|
2065 | 4036 | kfree(rtt_header); |
---|
2066 | 4037 | } |
---|
2067 | 4038 | } |
---|
| 4039 | + GCC_DIAGNOSTIC_POP(); |
---|
| 4040 | + |
---|
2068 | 4041 | kfree(rtt_status->rtt_config.target_info); |
---|
2069 | 4042 | kfree(dhd->rtt_state); |
---|
2070 | 4043 | dhd->rtt_state = NULL; |
---|
| 4044 | +#endif /* WL_CFG80211 */ |
---|
2071 | 4045 | return err; |
---|
2072 | 4046 | } |
---|