1 /* Copyright (c) 2015, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29
30
31 #include <netlink/genl/genl.h>
32 #include <netlink/genl/family.h>
33 #include <netlink/genl/ctrl.h>
34 #include <linux/rtnetlink.h>
35 #include <netinet/in.h>
36 #include "wifiloggercmd.h"
37 #include "wifilogger_event_defs.h"
38 #include "wifilogger_diag.h"
39 #include "wifilogger_vendor_tag_defs.h"
40 #include "pkt_stats.h"
41
42 #define MAX_CONNECTIVITY_EVENTS 16 // should match the value in wifi_logger.h
43 static event_remap_t events[MAX_CONNECTIVITY_EVENTS] = {
44 {WLAN_PE_DIAG_ASSOC_REQ_EVENT, WIFI_EVENT_ASSOCIATION_REQUESTED},
45 {WLAN_PE_DIAG_AUTH_COMP_EVENT, WIFI_EVENT_AUTH_COMPLETE},
46 {WLAN_PE_DIAG_CONNECTED, WIFI_EVENT_ASSOC_COMPLETE},
47 {WLAN_PE_DIAG_AUTH_START_EVENT, WIFI_EVENT_FW_AUTH_STARTED},
48 {WLAN_PE_DIAG_ASSOC_START_EVENT, WIFI_EVENT_FW_ASSOC_STARTED},
49 {WLAN_PE_DIAG_REASSOC_START_EVENT, WIFI_EVENT_FW_RE_ASSOC_STARTED},
50 {WLAN_PE_DIAG_SCAN_REQ_EVENT, WIFI_EVENT_DRIVER_SCAN_REQUESTED},
51 {WLAN_PE_DIAG_SCAN_RES_FOUND_EVENT, WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND},
52 {WLAN_PE_DIAG_SCAN_COMP_EVENT, WIFI_EVENT_DRIVER_SCAN_COMPLETE},
53 {WLAN_PE_DIAG_DISASSOC_REQ_EVENT, WIFI_EVENT_DISASSOCIATION_REQUESTED},
54 {WLAN_PE_DIAG_ASSOC_REQ_EVENT, WIFI_EVENT_RE_ASSOCIATION_REQUESTED},
55 {WLAN_PE_DIAG_ROAM_AUTH_START_EVENT, WIFI_EVENT_ROAM_AUTH_STARTED},
56 {WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT, WIFI_EVENT_ROAM_AUTH_COMPLETE},
57 {WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT, WIFI_EVENT_ROAM_ASSOC_STARTED},
58 {WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT, WIFI_EVENT_ROAM_ASSOC_COMPLETE},
59 {WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT, WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT},
60 };
61
addLoggerTlv(u16 type,u16 length,u8 * value,tlv_log * pOutTlv)62 tlv_log* addLoggerTlv(u16 type, u16 length, u8* value, tlv_log *pOutTlv)
63 {
64
65 pOutTlv->tag = type;
66 pOutTlv->length = length;
67 memcpy(&pOutTlv->value[0], value, length);
68
69 return((tlv_log *)((u8 *)pOutTlv + sizeof(tlv_log) + length));
70 }
71
add_reason_code_tag(tlv_log ** tlvs,u16 reason_code)72 int add_reason_code_tag(tlv_log **tlvs, u16 reason_code)
73 {
74 *tlvs = addLoggerTlv(WIFI_TAG_REASON_CODE, sizeof(u16),
75 (u8 *)&reason_code, *tlvs);
76 return (sizeof(tlv_log) + sizeof(u16));
77 }
78
add_status_tag(tlv_log ** tlvs,int status)79 int add_status_tag(tlv_log **tlvs, int status)
80 {
81 *tlvs = addLoggerTlv(WIFI_TAG_STATUS, sizeof(int),
82 (u8 *)&status, *tlvs);
83 return (sizeof(tlv_log) + sizeof(int));
84 }
85
update_connectivity_ring_buf(hal_info * info,wifi_ring_buffer_entry * rbe,u32 size)86 static wifi_error update_connectivity_ring_buf(hal_info *info,
87 wifi_ring_buffer_entry *rbe,
88 u32 size)
89 {
90 struct timeval time;
91 u32 total_length = size + sizeof(wifi_ring_buffer_entry);
92
93 rbe->entry_size = size;
94 rbe->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY |
95 RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
96 rbe->type = ENTRY_TYPE_CONNECT_EVENT;
97 gettimeofday(&time,NULL);
98 rbe->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
99
100 /* Write if verbose level and handler are set */
101 if (info->rb_infos[CONNECTIVITY_EVENTS_RB_ID].verbose_level >= 1 &&
102 info->on_ring_buffer_data) {
103 return ring_buffer_write(&info->rb_infos[CONNECTIVITY_EVENTS_RB_ID],
104 (u8*)rbe, total_length, 1, total_length);
105 }
106
107 return WIFI_SUCCESS;
108 }
109
110 #define SCAN_CAP_ENTRY_SIZE 1024
process_log_extscan_capabilities(hal_info * info,u8 * buf,int length)111 static wifi_error process_log_extscan_capabilities(hal_info *info,
112 u8* buf, int length)
113 {
114 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
115 wifi_ring_buffer_entry *pRingBufferEntry;
116 wlan_ext_scan_capabilities_payload_type *pScanCapabilities;
117 wifi_gscan_capabilities gscan_cap;
118 gscan_capabilities_vendor_data_t cap_vendor_data;
119 tlv_log *pTlv;
120 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
121 u8 out_buf[SCAN_CAP_ENTRY_SIZE];
122 wifi_error status;
123
124 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
125 memset(pRingBufferEntry, 0, SCAN_CAP_ENTRY_SIZE);
126 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
127 (pRingBufferEntry + 1);
128
129 pConnectEvent->event = WIFI_EVENT_G_SCAN_CAPABILITIES;
130 pTlv = &pConnectEvent->tlvs[0];
131
132 pScanCapabilities = (wlan_ext_scan_capabilities_payload_type *)buf;
133 pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID,
134 sizeof(pScanCapabilities->request_id),
135 (u8 *)&pScanCapabilities->request_id, pTlv);
136 tot_len += sizeof(tlv_log) + sizeof(pScanCapabilities->request_id);
137
138 gscan_cap.max_scan_cache_size =
139 pScanCapabilities->extscan_cache_capabilities.scan_cache_entry_size;
140 gscan_cap.max_scan_buckets =
141 pScanCapabilities->extscan_cache_capabilities.max_buckets;
142 gscan_cap.max_ap_cache_per_scan =
143 pScanCapabilities->extscan_cache_capabilities.max_bssid_per_scan;
144 gscan_cap.max_rssi_sample_size = FEATURE_NOT_SUPPORTED;
145 gscan_cap.max_scan_reporting_threshold =
146 pScanCapabilities->extscan_cache_capabilities.max_table_usage_threshold;
147 gscan_cap.max_hotlist_bssids =
148 pScanCapabilities->extscan_hotlist_monitor_capabilities.max_hotlist_entries;
149 gscan_cap.max_hotlist_ssids =
150 pScanCapabilities->extscan_capabilities.num_extscan_hotlist_ssid;
151 gscan_cap.max_significant_wifi_change_aps = FEATURE_NOT_SUPPORTED;
152 gscan_cap.max_bssid_history_entries = FEATURE_NOT_SUPPORTED;
153 gscan_cap.max_number_epno_networks =
154 pScanCapabilities->extscan_capabilities.num_epno_networks;
155 gscan_cap.max_number_epno_networks_by_ssid =
156 pScanCapabilities->extscan_capabilities.num_epno_networks;
157 gscan_cap.max_number_of_white_listed_ssid =
158 pScanCapabilities->extscan_capabilities.num_roam_ssid_whitelist;
159
160 pTlv = addLoggerTlv(WIFI_TAG_GSCAN_CAPABILITIES,
161 sizeof(wifi_gscan_capabilities),
162 (u8 *)&gscan_cap, pTlv);
163 tot_len += sizeof(tlv_log) + sizeof(wifi_gscan_capabilities);
164
165 cap_vendor_data.hotlist_mon_table_id =
166 pScanCapabilities->extscan_hotlist_monitor_capabilities.table_id;
167 cap_vendor_data.wlan_hotlist_entry_size =
168 pScanCapabilities->extscan_hotlist_monitor_capabilities.wlan_hotlist_entry_size;
169 cap_vendor_data.cache_cap_table_id =
170 pScanCapabilities->extscan_cache_capabilities.table_id;
171 cap_vendor_data.requestor_id =
172 pScanCapabilities->extscan_capabilities.requestor_id;
173 cap_vendor_data.vdev_id =
174 pScanCapabilities->extscan_capabilities.vdev_id;
175 cap_vendor_data.num_extscan_cache_tables =
176 pScanCapabilities->extscan_capabilities.num_extscan_cache_tables;
177 cap_vendor_data.num_wlan_change_monitor_tables =
178 pScanCapabilities->extscan_capabilities.num_wlan_change_monitor_tables;
179 cap_vendor_data.num_hotlist_monitor_tables =
180 pScanCapabilities->extscan_capabilities.num_hotlist_monitor_tables;
181 cap_vendor_data.rtt_one_sided_supported =
182 pScanCapabilities->extscan_capabilities.rtt_one_sided_supported;
183 cap_vendor_data.rtt_11v_supported =
184 pScanCapabilities->extscan_capabilities.rtt_11v_supported;
185 cap_vendor_data.rtt_ftm_supported =
186 pScanCapabilities->extscan_capabilities.rtt_ftm_supported;
187 cap_vendor_data.num_extscan_cache_capabilities =
188 pScanCapabilities->extscan_capabilities.num_extscan_cache_capabilities;
189 cap_vendor_data.num_extscan_wlan_change_capabilities =
190 pScanCapabilities->extscan_capabilities.num_extscan_wlan_change_capabilities;
191 cap_vendor_data.num_extscan_hotlist_capabilities =
192 pScanCapabilities->extscan_capabilities.num_extscan_hotlist_capabilities;
193 cap_vendor_data.num_roam_bssid_blacklist =
194 pScanCapabilities->extscan_capabilities.num_roam_bssid_blacklist;
195 cap_vendor_data.num_roam_bssid_preferred_list =
196 pScanCapabilities->extscan_capabilities.num_roam_bssid_preferred_list;
197
198 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
199 sizeof(gscan_capabilities_vendor_data_t),
200 (u8 *)&cap_vendor_data, pTlv);
201 tot_len += sizeof(tlv_log) + sizeof(gscan_capabilities_vendor_data_t);
202
203 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
204 if (status != WIFI_SUCCESS) {
205 ALOGE("Failed to write ext scan capabilities event into ring buffer");
206 }
207 return status;
208 }
209
process_bt_coex_scan_event(hal_info * info,u32 id,u8 * buf,int length)210 static wifi_error process_bt_coex_scan_event(hal_info *info,
211 u32 id, u8* buf, int length)
212 {
213 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
214 wifi_ring_buffer_entry *pRingBufferEntry;
215 tlv_log *pTlv;
216 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
217 u8 out_buf[RING_BUF_ENTRY_SIZE];
218 wifi_error status;
219
220 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
221 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
222 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
223 (pRingBufferEntry + 1);
224 pTlv = &pConnectEvent->tlvs[0];
225
226 if (id == EVENT_WLAN_BT_COEX_BT_SCAN_START) {
227 wlan_bt_coex_bt_scan_start_payload_type *pBtScanStart;
228 bt_coex_bt_scan_start_vendor_data_t btScanStartVenData;
229
230 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCAN_START;
231
232 pBtScanStart = (wlan_bt_coex_bt_scan_start_payload_type *)buf;
233 btScanStartVenData.scan_type = pBtScanStart->scan_type;
234 btScanStartVenData.scan_bitmap = pBtScanStart->scan_bitmap;
235
236 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
237 sizeof(bt_coex_bt_scan_start_vendor_data_t),
238 (u8 *)&btScanStartVenData, pTlv);
239 tot_len += sizeof(tlv_log) +
240 sizeof(bt_coex_bt_scan_start_vendor_data_t);
241 } else if(id == EVENT_WLAN_BT_COEX_BT_SCAN_STOP) {
242 wlan_bt_coex_bt_scan_stop_payload_type *pBtScanStop;
243 bt_coex_bt_scan_stop_vendor_data_t btScanStopVenData;
244
245 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCAN_STOP;
246
247 pBtScanStop = (wlan_bt_coex_bt_scan_stop_payload_type *)buf;
248 btScanStopVenData.scan_type = pBtScanStop->scan_type;
249 btScanStopVenData.scan_bitmap = pBtScanStop->scan_bitmap;
250
251 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
252 sizeof(bt_coex_bt_scan_stop_vendor_data_t),
253 (u8 *)&btScanStopVenData, pTlv);
254 tot_len += sizeof(tlv_log) + sizeof(bt_coex_bt_scan_stop_vendor_data_t);
255 }
256 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
257 if (status != WIFI_SUCCESS) {
258 ALOGE("Failed to write bt_coex_scan event into ring buffer");
259 }
260
261 return status;
262 }
263
process_bt_coex_event(hal_info * info,u32 id,u8 * buf,int length)264 static wifi_error process_bt_coex_event(hal_info *info, u32 id,
265 u8* buf, int length)
266 {
267 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
268 wifi_ring_buffer_entry *pRingBufferEntry;
269 tlv_log *pTlv;
270 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
271 u8 out_buf[RING_BUF_ENTRY_SIZE];
272 u8 link_id, link_state, link_role, link_type = 0, Rsco = 0;
273 u16 Tsco = 0;
274 wifi_error status;
275 bt_coex_hid_vendor_data_t btCoexHidVenData;
276
277 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
278 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
279 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
280 (pRingBufferEntry + 1);
281
282 switch (id) {
283 case EVENT_WLAN_BT_COEX_BT_SCO_START:
284 {
285 wlan_bt_coex_bt_sco_start_payload_type *pBtCoexStartPL;
286 pBtCoexStartPL = (wlan_bt_coex_bt_sco_start_payload_type *)buf;
287
288 link_id = pBtCoexStartPL->link_id;
289 link_state = pBtCoexStartPL->link_state;
290 link_role = pBtCoexStartPL->link_role;
291 link_type = pBtCoexStartPL->link_type;
292 Tsco = pBtCoexStartPL->Tsco;
293 Rsco = pBtCoexStartPL->Rsco;
294
295 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCO_START;
296 }
297 break;
298 case EVENT_WLAN_BT_COEX_BT_SCO_STOP:
299 {
300 wlan_bt_coex_bt_sco_stop_payload_type *pBtCoexStopPL;
301 pBtCoexStopPL = (wlan_bt_coex_bt_sco_stop_payload_type *)buf;
302
303 link_id = pBtCoexStopPL->link_id;
304 link_state = pBtCoexStopPL->link_state;
305 link_role = pBtCoexStopPL->link_role;
306 link_type = pBtCoexStopPL->link_type;
307 Tsco = pBtCoexStopPL->Tsco;
308 Rsco = pBtCoexStopPL->Rsco;
309
310 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCO_STOP;
311 }
312 break;
313 case EVENT_WLAN_BT_COEX_BT_HID_START:
314 {
315 wlan_bt_coex_bt_hid_start_payload_type *pBtCoexHidStartPL;
316 pBtCoexHidStartPL = (wlan_bt_coex_bt_hid_start_payload_type *)buf;
317
318 link_id = pBtCoexHidStartPL->link_id;
319 link_state = pBtCoexHidStartPL->link_state;
320 link_role = pBtCoexHidStartPL->link_role;
321 btCoexHidVenData.Tsniff = pBtCoexHidStartPL->Tsniff;
322 btCoexHidVenData.attempts = pBtCoexHidStartPL->attempts;
323
324 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_HID_START;
325 }
326 break;
327 case EVENT_WLAN_BT_COEX_BT_HID_STOP:
328 {
329 wlan_bt_coex_bt_hid_stop_payload_type *pBtCoexHidStopPL;
330 pBtCoexHidStopPL = (wlan_bt_coex_bt_hid_stop_payload_type *)buf;
331
332 link_id = pBtCoexHidStopPL->link_id;
333 link_state = pBtCoexHidStopPL->link_state;
334 link_role = pBtCoexHidStopPL->link_role;
335 btCoexHidVenData.Tsniff = pBtCoexHidStopPL->Tsniff;
336 btCoexHidVenData.attempts = pBtCoexHidStopPL->attempts;
337
338 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_HID_STOP;
339 }
340 break;
341 default:
342 return WIFI_SUCCESS;
343 }
344
345 pTlv = &pConnectEvent->tlvs[0];
346 pTlv = addLoggerTlv(WIFI_TAG_LINK_ID, sizeof(link_id), &link_id, pTlv);
347 tot_len += sizeof(tlv_log) + sizeof(link_id);
348
349 pTlv = addLoggerTlv(WIFI_TAG_LINK_ROLE, sizeof(link_role),
350 &link_role, pTlv);
351 tot_len += sizeof(tlv_log) + sizeof(link_role);
352
353 pTlv = addLoggerTlv(WIFI_TAG_LINK_STATE, sizeof(link_state),
354 &link_state, pTlv);
355 tot_len += sizeof(tlv_log) + sizeof(link_state);
356
357 if ((pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_SCO_START) ||
358 (pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_SCO_STOP)) {
359 pTlv = addLoggerTlv(WIFI_TAG_LINK_TYPE, sizeof(link_type),
360 &link_type, pTlv);
361 tot_len += sizeof(tlv_log) + sizeof(link_type);
362
363 pTlv = addLoggerTlv(WIFI_TAG_TSCO, sizeof(Tsco), (u8 *)&Tsco, pTlv);
364 tot_len += sizeof(tlv_log) + sizeof(Tsco);
365
366 pTlv = addLoggerTlv(WIFI_TAG_RSCO, sizeof(Rsco), &Rsco, pTlv);
367 tot_len += sizeof(tlv_log) + sizeof(Rsco);
368 } else if ((pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_HID_START) ||
369 (pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_HID_STOP)) {
370 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
371 sizeof(bt_coex_hid_vendor_data_t),
372 (u8 *)&btCoexHidVenData, pTlv);
373 tot_len += sizeof(tlv_log) + sizeof(bt_coex_hid_vendor_data_t);
374 }
375
376 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
377 if (status != WIFI_SUCCESS) {
378 ALOGE("Failed to write bt_coex_event into ring buffer");
379 }
380
381 return status;
382 }
383
process_extscan_event(hal_info * info,u32 id,u8 * buf,int length)384 static wifi_error process_extscan_event(hal_info *info, u32 id,
385 u8* buf, int length)
386 {
387 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
388 wifi_ring_buffer_entry *pRingBufferEntry;
389 tlv_log *pTlv;
390 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
391 u8 out_buf[RING_BUF_ENTRY_SIZE];
392 wifi_error status;
393
394 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
395 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
396 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
397 (pRingBufferEntry + 1);
398 pTlv = &pConnectEvent->tlvs[0];
399
400 switch (id) {
401 case EVENT_WLAN_EXTSCAN_CYCLE_STARTED:
402 {
403 ext_scan_cycle_vendor_data_t extScanCycleVenData;
404 wlan_ext_scan_cycle_started_payload_type *pExtScanCycleStarted;
405 pConnectEvent->event = WIFI_EVENT_G_SCAN_CYCLE_STARTED;
406 pExtScanCycleStarted =
407 (wlan_ext_scan_cycle_started_payload_type *)buf;
408 pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID, sizeof(u32),
409 (u8 *)&pExtScanCycleStarted->scan_id, pTlv);
410 tot_len += sizeof(tlv_log) + sizeof(u32);
411
412 extScanCycleVenData.timer_tick = pExtScanCycleStarted->timer_tick;
413 extScanCycleVenData.scheduled_bucket_mask =
414 pExtScanCycleStarted->scheduled_bucket_mask;
415 extScanCycleVenData.scan_cycle_count =
416 pExtScanCycleStarted->scan_cycle_count;
417
418 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
419 sizeof(ext_scan_cycle_vendor_data_t),
420 (u8 *)&extScanCycleVenData, pTlv);
421 tot_len += sizeof(tlv_log) + sizeof(ext_scan_cycle_vendor_data_t);
422 }
423 break;
424 case EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED:
425 {
426 ext_scan_cycle_vendor_data_t extScanCycleVenData;
427 wlan_ext_scan_cycle_completed_payload_type *pExtScanCycleCompleted;
428 pConnectEvent->event = WIFI_EVENT_G_SCAN_CYCLE_COMPLETED;
429 pExtScanCycleCompleted =
430 (wlan_ext_scan_cycle_completed_payload_type *)buf;
431 pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID, sizeof(u32),
432 (u8 *)&pExtScanCycleCompleted->scan_id, pTlv);
433 tot_len += sizeof(tlv_log) + sizeof(u32);
434
435 extScanCycleVenData.timer_tick = pExtScanCycleCompleted->timer_tick;
436 extScanCycleVenData.scheduled_bucket_mask =
437 pExtScanCycleCompleted->scheduled_bucket_mask;
438 extScanCycleVenData.scan_cycle_count =
439 pExtScanCycleCompleted->scan_cycle_count;
440
441 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
442 sizeof(ext_scan_cycle_vendor_data_t),
443 (u8 *)&extScanCycleVenData, pTlv);
444 tot_len += sizeof(tlv_log) + sizeof(ext_scan_cycle_vendor_data_t);
445 }
446 break;
447 case EVENT_WLAN_EXTSCAN_BUCKET_STARTED:
448 {
449 wlan_ext_scan_bucket_started_payload_type *pExtScanBucketStarted;
450 u32 bucket_id;
451 pConnectEvent->event = WIFI_EVENT_G_SCAN_BUCKET_STARTED;
452 pExtScanBucketStarted =
453 (wlan_ext_scan_bucket_started_payload_type *)buf;
454 bucket_id = (u32)pExtScanBucketStarted->bucket_id;
455 pTlv = addLoggerTlv(WIFI_TAG_BUCKET_ID, sizeof(u32),
456 (u8 *)&bucket_id, pTlv);
457 tot_len += sizeof(tlv_log) + sizeof(u32);
458 }
459 break;
460 case EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED:
461 {
462 wlan_ext_scan_bucket_completed_payload_type *pExtScanBucketCmpleted;
463 u32 bucket_id;
464 pConnectEvent->event = WIFI_EVENT_G_SCAN_BUCKET_COMPLETED;
465 pExtScanBucketCmpleted =
466 (wlan_ext_scan_bucket_completed_payload_type *)buf;
467 bucket_id = (u32)pExtScanBucketCmpleted->bucket_id;
468 pTlv = addLoggerTlv(WIFI_TAG_BUCKET_ID, sizeof(u32),
469 (u8 *)&bucket_id, pTlv);
470 tot_len += sizeof(tlv_log) + sizeof(u32);
471 }
472 break;
473 case EVENT_WLAN_EXTSCAN_FEATURE_STOP:
474 {
475 wlan_ext_scan_feature_stop_payload_type *pExtScanStop;
476 pConnectEvent->event = WIFI_EVENT_G_SCAN_STOP;
477 pExtScanStop = (wlan_ext_scan_feature_stop_payload_type *)buf;
478 pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID,
479 sizeof(pExtScanStop->request_id),
480 (u8 *)&pExtScanStop->request_id, pTlv);
481 tot_len += sizeof(tlv_log) +
482 sizeof(wlan_ext_scan_feature_stop_payload_type);
483 }
484 break;
485 case EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE:
486 {
487 wlan_ext_scan_results_available_payload_type *pExtScanResultsAvail;
488 ext_scan_results_available_vendor_data_t extScanResultsAvailVenData;
489 u32 request_id;
490 pConnectEvent->event = WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE;
491 pExtScanResultsAvail =
492 (wlan_ext_scan_results_available_payload_type *)buf;
493 request_id = pExtScanResultsAvail->request_id;
494 pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID, sizeof(u32),
495 (u8 *)&request_id, pTlv);
496 tot_len += sizeof(tlv_log) + sizeof(u32);
497
498 extScanResultsAvailVenData.table_type =
499 pExtScanResultsAvail->table_type;
500 extScanResultsAvailVenData.entries_in_use =
501 pExtScanResultsAvail->entries_in_use;
502 extScanResultsAvailVenData.maximum_entries =
503 pExtScanResultsAvail->maximum_entries;
504 extScanResultsAvailVenData.scan_count_after_getResults =
505 pExtScanResultsAvail->scan_count_after_getResults;
506 extScanResultsAvailVenData.threshold_num_scans =
507 pExtScanResultsAvail->threshold_num_scans;
508
509 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
510 sizeof(ext_scan_results_available_vendor_data_t),
511 (u8 *)&extScanResultsAvailVenData, pTlv);
512 tot_len += sizeof(tlv_log) +
513 sizeof(ext_scan_results_available_vendor_data_t);
514 }
515 break;
516 }
517
518 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
519 if (status != WIFI_SUCCESS) {
520 ALOGE("Failed to write ext_scan event into ring buffer");
521 }
522
523 return status;
524 }
525
process_addba_success_event(hal_info * info,u8 * buf,int length)526 static wifi_error process_addba_success_event(hal_info *info,
527 u8* buf, int length)
528 {
529 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
530 wifi_ring_buffer_entry *pRingBufferEntry;
531 tlv_log *pTlv;
532 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
533 u8 out_buf[RING_BUF_ENTRY_SIZE];
534 wlan_add_block_ack_success_payload_type *pAddBASuccess;
535 addba_success_vendor_data_t addBASuccessVenData;
536 wifi_error status;
537
538 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
539 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
540 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
541 (pRingBufferEntry + 1);
542 pAddBASuccess = (wlan_add_block_ack_success_payload_type *)buf;
543
544 addBASuccessVenData.ucBaTid = pAddBASuccess->ucBaTid;
545 addBASuccessVenData.ucBaBufferSize = pAddBASuccess->ucBaBufferSize;
546 addBASuccessVenData.ucBaSSN = pAddBASuccess->ucBaSSN;
547 addBASuccessVenData.fInitiator = pAddBASuccess->fInitiator;
548
549 pConnectEvent->event = WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE;
550 pTlv = &pConnectEvent->tlvs[0];
551 pTlv = addLoggerTlv(WIFI_TAG_ADDR, sizeof(pAddBASuccess->ucBaPeerMac),
552 (u8 *)pAddBASuccess->ucBaPeerMac, pTlv);
553 tot_len += sizeof(tlv_log) + sizeof(pAddBASuccess->ucBaPeerMac);
554
555 tot_len += add_status_tag(&pTlv, (int)ADDBA_SUCCESS);
556
557 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
558 sizeof(addba_success_vendor_data_t),
559 (u8 *)&addBASuccessVenData, pTlv);
560 tot_len += sizeof(tlv_log) + sizeof(addba_success_vendor_data_t);
561
562 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
563 if (status != WIFI_SUCCESS) {
564 ALOGE("Failed to write addba event into ring buffer");
565 }
566
567 return status;
568 }
569
process_addba_failed_event(hal_info * info,u8 * buf,int length)570 static wifi_error process_addba_failed_event(hal_info *info,
571 u8* buf, int length)
572 {
573 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
574 wifi_ring_buffer_entry *pRingBufferEntry;
575 tlv_log *pTlv;
576 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
577 u8 out_buf[RING_BUF_ENTRY_SIZE];
578 wlan_add_block_ack_failed_payload_type *pAddBAFailed;
579 addba_failed_vendor_data_t addBAFailedVenData;
580 wifi_error status;
581
582 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
583 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
584 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
585 (pRingBufferEntry + 1);
586
587 pAddBAFailed = (wlan_add_block_ack_failed_payload_type *)buf;
588 addBAFailedVenData.ucBaTid = pAddBAFailed->ucBaTid;
589 addBAFailedVenData.fInitiator = pAddBAFailed->fInitiator;
590
591 pConnectEvent->event = WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE;
592 pTlv = &pConnectEvent->tlvs[0];
593 pTlv = addLoggerTlv(WIFI_TAG_ADDR, sizeof(pAddBAFailed->ucBaPeerMac),
594 (u8 *)pAddBAFailed->ucBaPeerMac, pTlv);
595 tot_len += sizeof(tlv_log) + sizeof(pAddBAFailed->ucBaPeerMac);
596
597 tot_len += add_status_tag(&pTlv, (int)ADDBA_FAILURE);
598
599 tot_len += add_reason_code_tag(&pTlv, (u16)pAddBAFailed->ucReasonCode);
600
601 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
602 sizeof(addba_failed_vendor_data_t),
603 (u8 *)&addBAFailedVenData, pTlv);
604 tot_len += sizeof(tlv_log) + sizeof(addba_failed_vendor_data_t);
605
606 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
607 if (status != WIFI_SUCCESS) {
608 ALOGE("Failed to write addba event into ring buffer");
609 }
610
611 return status;
612 }
613
process_roam_event(hal_info * info,u32 id,u8 * buf,int length)614 static wifi_error process_roam_event(hal_info *info, u32 id,
615 u8* buf, int length)
616 {
617 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
618 wifi_ring_buffer_entry *pRingBufferEntry;
619 tlv_log *pTlv;
620 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
621 u8 out_buf[RING_BUF_ENTRY_SIZE];
622 wifi_error status;
623
624 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
625 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
626 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
627 (pRingBufferEntry + 1);
628
629 switch (id)
630 {
631 case EVENT_WLAN_ROAM_SCAN_STARTED:
632 {
633 wlan_roam_scan_started_payload_type *pRoamScanStarted;
634 roam_scan_started_vendor_data_t roamScanStartedVenData;
635 pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_STARTED;
636 pRoamScanStarted = (wlan_roam_scan_started_payload_type *)buf;
637 pTlv = &pConnectEvent->tlvs[0];
638 pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID,
639 sizeof(pRoamScanStarted->scan_id),
640 (u8 *)&pRoamScanStarted->scan_id, pTlv);
641 tot_len += sizeof(tlv_log) + sizeof(pRoamScanStarted->scan_id);
642 roamScanStartedVenData.roam_scan_flags =
643 pRoamScanStarted->roam_scan_flags;
644 roamScanStartedVenData.cur_rssi = pRoamScanStarted->cur_rssi;
645 memcpy(roamScanStartedVenData.scan_params,
646 pRoamScanStarted->scan_params,
647 sizeof(roamScanStartedVenData.scan_params));
648 memcpy(roamScanStartedVenData.scan_channels,
649 pRoamScanStarted->scan_channels,
650 sizeof(roamScanStartedVenData.scan_channels));
651 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
652 sizeof(roam_scan_started_vendor_data_t),
653 (u8 *)&roamScanStartedVenData, pTlv);
654 tot_len += sizeof(tlv_log) +
655 sizeof(roam_scan_started_vendor_data_t);
656 }
657 break;
658 case EVENT_WLAN_ROAM_SCAN_COMPLETE:
659 {
660 wlan_roam_scan_complete_payload_type *pRoamScanComplete;
661 roam_scan_complete_vendor_data_t roamScanCompleteVenData;
662 pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_COMPLETE;
663 pRoamScanComplete = (wlan_roam_scan_complete_payload_type *)buf;
664 pTlv = &pConnectEvent->tlvs[0];
665
666 pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID,
667 sizeof(pRoamScanComplete->scan_id),
668 (u8 *)&pRoamScanComplete->scan_id, pTlv);
669 tot_len += sizeof(tlv_log) + sizeof(pRoamScanComplete->scan_id);
670
671 roamScanCompleteVenData.reason = pRoamScanComplete->reason;
672 roamScanCompleteVenData.completion_flags =
673 pRoamScanComplete->completion_flags;
674 roamScanCompleteVenData.num_candidate =
675 pRoamScanComplete->num_candidate;
676 roamScanCompleteVenData.flags = pRoamScanComplete->flags;
677
678 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
679 sizeof(roam_scan_complete_vendor_data_t),
680 (u8 *)&roamScanCompleteVenData, pTlv);
681 tot_len += sizeof(tlv_log) +
682 sizeof(roam_scan_complete_vendor_data_t);
683 }
684 break;
685 case EVENT_WLAN_ROAM_CANDIDATE_FOUND:
686 {
687 wlan_roam_candidate_found_payload_type *pRoamCandidateFound;
688 roam_candidate_found_vendor_data_t roamCandidateFoundVendata;
689 pConnectEvent->event = WIFI_EVENT_ROAM_CANDIDATE_FOUND;
690 pRoamCandidateFound = (wlan_roam_candidate_found_payload_type *)buf;
691 pTlv = &pConnectEvent->tlvs[0];
692 pTlv = addLoggerTlv(WIFI_TAG_CHANNEL,
693 sizeof(pRoamCandidateFound->channel),
694 (u8 *)&pRoamCandidateFound->channel, pTlv);
695 tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->channel);
696
697 pTlv = addLoggerTlv(WIFI_TAG_RSSI,
698 sizeof(pRoamCandidateFound->rssi),
699 (u8 *)&pRoamCandidateFound->rssi, pTlv);
700 tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->rssi);
701
702 pTlv = addLoggerTlv(WIFI_TAG_BSSID,
703 sizeof(pRoamCandidateFound->bssid),
704 (u8 *)pRoamCandidateFound->bssid, pTlv);
705 tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->bssid);
706
707 pTlv = addLoggerTlv(WIFI_TAG_SSID,
708 sizeof(pRoamCandidateFound->ssid),
709 (u8 *)pRoamCandidateFound->ssid, pTlv);
710 tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->ssid);
711
712 roamCandidateFoundVendata.auth_mode =
713 pRoamCandidateFound->auth_mode;
714 roamCandidateFoundVendata.ucast_cipher =
715 pRoamCandidateFound->ucast_cipher;
716 roamCandidateFoundVendata.mcast_cipher =
717 pRoamCandidateFound->mcast_cipher;
718 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
719 sizeof(roam_candidate_found_vendor_data_t),
720 (u8 *)&roamCandidateFoundVendata, pTlv);
721 tot_len += sizeof(tlv_log) +
722 sizeof(roam_candidate_found_vendor_data_t);
723 }
724 break;
725 case EVENT_WLAN_ROAM_SCAN_CONFIG:
726 {
727 wlan_roam_scan_config_payload_type *pRoamScanConfig;
728 roam_scan_config_vendor_data_t roamScanConfigVenData;
729
730 pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_CONFIG;
731 pRoamScanConfig = (wlan_roam_scan_config_payload_type *)buf;
732
733 pTlv = &pConnectEvent->tlvs[0];
734
735 roamScanConfigVenData.flags = pRoamScanConfig->flags;
736 memcpy(roamScanConfigVenData.roam_scan_config,
737 pRoamScanConfig->roam_scan_config,
738 sizeof(roamScanConfigVenData.roam_scan_config));
739
740 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
741 sizeof(roam_scan_config_vendor_data_t),
742 (u8 *)&roamScanConfigVenData, pTlv);
743 tot_len += sizeof(tlv_log) +
744 sizeof(roam_scan_config_vendor_data_t);
745 }
746 break;
747 }
748
749 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
750 if (status != WIFI_SUCCESS) {
751 ALOGE("Failed to write roam event into ring buffer");
752 }
753
754 return status;
755 }
756
process_firmware_prints(hal_info * info,u8 * buf,u16 length)757 wifi_error process_firmware_prints(hal_info *info, u8 *buf, u16 length)
758 {
759 wifi_ring_buffer_entry rb_entry_hdr;
760 struct timeval time;
761 wifi_error status;
762
763 rb_entry_hdr.entry_size = length;
764 rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
765 rb_entry_hdr.type = ENTRY_TYPE_DATA;
766 gettimeofday(&time, NULL);
767 rb_entry_hdr.timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
768
769 /* Write if verbose and handler is set */
770 if (info->rb_infos[FIRMWARE_PRINTS_RB_ID].verbose_level >= 1 &&
771 info->on_ring_buffer_data) {
772 /* Write header and payload separately to avoid
773 * complete payload memcpy */
774 status = ring_buffer_write(&info->rb_infos[FIRMWARE_PRINTS_RB_ID],
775 (u8*)&rb_entry_hdr,
776 sizeof(wifi_ring_buffer_entry),
777 0,
778 sizeof(wifi_ring_buffer_entry) + length);
779 if (status != WIFI_SUCCESS) {
780 ALOGE("Failed to write firmware prints rb header %d", status);
781 return status;
782 }
783 status = ring_buffer_write(&info->rb_infos[FIRMWARE_PRINTS_RB_ID],
784 buf, length, 1, length);
785 if (status != WIFI_SUCCESS) {
786 ALOGE("Failed to write firmware prints rb payload %d", status);
787 return status;
788 }
789 }
790
791 return WIFI_SUCCESS;
792 }
793
process_fw_diag_msg(hal_info * info,u8 * buf,u16 length)794 static wifi_error process_fw_diag_msg(hal_info *info, u8* buf, u16 length)
795 {
796 u16 count = 0, id, payloadlen;
797 wifi_error status;
798 fw_diag_msg_hdr_t *diag_msg_hdr;
799
800 buf += 4;
801 length -= 4;
802
803 while (length > (count + sizeof(fw_diag_msg_hdr_t))) {
804 diag_msg_hdr = (fw_diag_msg_hdr_t *)(buf + count);
805
806 id = diag_msg_hdr->diag_id;
807 payloadlen = diag_msg_hdr->u.payload_len;
808
809 switch (diag_msg_hdr->diag_event_type) {
810 case WLAN_DIAG_TYPE_EVENT:
811 {
812 switch (id) {
813 case EVENT_WLAN_BT_COEX_BT_SCO_START:
814 case EVENT_WLAN_BT_COEX_BT_SCO_STOP:
815 case EVENT_WLAN_BT_COEX_BT_HID_START:
816 case EVENT_WLAN_BT_COEX_BT_HID_STOP:
817 status = process_bt_coex_event(info, id,
818 diag_msg_hdr->payload,
819 payloadlen);
820 if (status != WIFI_SUCCESS) {
821 ALOGE("Failed to process bt_coex event");
822 return status;
823 }
824 break;
825 case EVENT_WLAN_BT_COEX_BT_SCAN_START:
826 case EVENT_WLAN_BT_COEX_BT_SCAN_STOP:
827 status = process_bt_coex_scan_event(info, id,
828 diag_msg_hdr->payload,
829 payloadlen);
830 if (status != WIFI_SUCCESS) {
831 ALOGE("Failed to process bt_coex_scan event");
832 return status;
833 }
834 break;
835 case EVENT_WLAN_EXTSCAN_CYCLE_STARTED:
836 case EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED:
837 case EVENT_WLAN_EXTSCAN_BUCKET_STARTED:
838 case EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED:
839 case EVENT_WLAN_EXTSCAN_FEATURE_STOP:
840 case EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE:
841 status = process_extscan_event(info, id,
842 diag_msg_hdr->payload,
843 payloadlen);
844 if (status != WIFI_SUCCESS) {
845 ALOGE("Failed to process extscan event");
846 return status;
847 }
848 break;
849 case EVENT_WLAN_ROAM_SCAN_STARTED:
850 case EVENT_WLAN_ROAM_SCAN_COMPLETE:
851 case EVENT_WLAN_ROAM_CANDIDATE_FOUND:
852 case EVENT_WLAN_ROAM_SCAN_CONFIG:
853 status = process_roam_event(info, id,
854 diag_msg_hdr->payload,
855 payloadlen);
856 if (status != WIFI_SUCCESS) {
857 ALOGE("Failed to process roam event");
858 return status;
859 }
860 break;
861 case EVENT_WLAN_ADD_BLOCK_ACK_SUCCESS:
862 status = process_addba_success_event(info,
863 diag_msg_hdr->payload,
864 payloadlen);
865 if (status != WIFI_SUCCESS) {
866 ALOGE("Failed to process addba success event");
867 return status;
868 }
869 break;
870 case EVENT_WLAN_ADD_BLOCK_ACK_FAILED:
871 status = process_addba_failed_event(info,
872 diag_msg_hdr->payload,
873 payloadlen);
874 if (status != WIFI_SUCCESS) {
875 ALOGE("Failed to process addba failed event");
876 return status;
877 }
878 break;
879 default:
880 return WIFI_SUCCESS;
881 }
882 }
883 break;
884 case WLAN_DIAG_TYPE_LOG:
885 {
886 id = diag_msg_hdr->diag_id;
887 payloadlen = diag_msg_hdr->u.payload_len;
888
889 switch (id) {
890 case LOG_WLAN_EXTSCAN_CAPABILITIES:
891 status = process_log_extscan_capabilities(info,
892 diag_msg_hdr->payload,
893 payloadlen);
894 if (status != WIFI_SUCCESS) {
895 ALOGE("Failed to process extscan capabilities");
896 return status;
897 }
898 break;
899 default:
900 return WIFI_SUCCESS;
901 }
902 }
903 break;
904 case WLAN_DIAG_TYPE_MSG:
905 {
906 /* Length field is only one byte for WLAN_DIAG_TYPE_MSG */
907 payloadlen = diag_msg_hdr->u.msg_hdr.payload_len;
908 process_firmware_prints(info, (u8 *)diag_msg_hdr,
909 payloadlen + sizeof(fw_diag_msg_hdr_t));
910 }
911 break;
912 default:
913 return WIFI_SUCCESS;
914 }
915 count += payloadlen + sizeof(fw_diag_msg_hdr_t);
916 }
917 return WIFI_SUCCESS;
918 }
919
remap_event(int in_event,int * out_event)920 static wifi_error remap_event(int in_event, int *out_event)
921 {
922 int i = 0;
923 while (i < MAX_CONNECTIVITY_EVENTS) {
924 if (events[i].q_event == in_event) {
925 *out_event = events[i].g_event;
926 return WIFI_SUCCESS;
927 }
928 i++;
929 }
930 return WIFI_ERROR_UNKNOWN;
931 }
932
process_wlan_pe_event(hal_info * info,u8 * buf,int length)933 static wifi_error process_wlan_pe_event(hal_info *info, u8* buf, int length)
934 {
935 wlan_pe_event_t *pWlanPeEvent;
936 pe_event_vendor_data_t peEventVenData;
937 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
938 wifi_ring_buffer_entry *pRingBufferEntry;
939 tlv_log *pTlv;
940 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
941 u8 out_buf[RING_BUF_ENTRY_SIZE];
942 wifi_error status;
943
944 pWlanPeEvent = (wlan_pe_event_t *)buf;
945
946 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
947 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
948 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
949 (pRingBufferEntry + 1);
950
951 status = remap_event(pWlanPeEvent->event_type,
952 (int *)&pConnectEvent->event);
953 if (status != WIFI_SUCCESS)
954 return status;
955
956 pTlv = &pConnectEvent->tlvs[0];
957 pTlv = addLoggerTlv(WIFI_TAG_BSSID, sizeof(pWlanPeEvent->bssid),
958 (u8 *)pWlanPeEvent->bssid, pTlv);
959 tot_len += sizeof(tlv_log) + sizeof(pWlanPeEvent->bssid);
960
961 tot_len += add_status_tag(&pTlv, (int)pWlanPeEvent->status);
962
963 pTlv = addLoggerTlv(WIFI_TAG_REASON_CODE, sizeof(pWlanPeEvent->reason_code),
964 (u8 *)&pWlanPeEvent->reason_code, pTlv);
965 tot_len += sizeof(tlv_log) + sizeof(pWlanPeEvent->reason_code);
966
967 peEventVenData.sme_state = pWlanPeEvent->sme_state;
968 peEventVenData.mlm_state = pWlanPeEvent->mlm_state;
969
970 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
971 sizeof(pe_event_vendor_data_t),
972 (u8 *)&peEventVenData, pTlv);
973 tot_len += sizeof(tlv_log) + sizeof(pe_event_vendor_data_t);
974
975 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
976 if (status != WIFI_SUCCESS) {
977 ALOGE("Failed to write pe event into ring buffer");
978 }
979
980 return status;
981 }
982
process_wlan_eapol_event(hal_info * info,u8 * buf,int length)983 static wifi_error process_wlan_eapol_event(hal_info *info, u8* buf, int length)
984 {
985 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
986 wlan_eapol_event_t *pWlanEapolEvent;
987 wifi_ring_buffer_entry *pRingBufferEntry;
988 u8 out_buf[RING_BUF_ENTRY_SIZE];
989 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
990 tlv_log *pTlv;
991 u32 eapol_msg_type = 0;
992 wifi_error status;
993
994 pWlanEapolEvent = (wlan_eapol_event_t *)buf;
995 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
996 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
997 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
998 (pRingBufferEntry + 1);
999
1000 if (pWlanEapolEvent->event_sub_type ==
1001 WLAN_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED)
1002 pConnectEvent->event = WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED;
1003 else
1004 pConnectEvent->event = WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED;
1005
1006 pTlv = &pConnectEvent->tlvs[0];
1007
1008 if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M1_MASK)
1009 eapol_msg_type = 1;
1010 else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M2_MASK)
1011 eapol_msg_type = 2;
1012 else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M3_MASK)
1013 eapol_msg_type = 3;
1014 else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M4_MASK)
1015 eapol_msg_type = 4;
1016 else
1017 ALOGI("Unknown EAPOL message type \n");
1018 pTlv = addLoggerTlv(WIFI_TAG_EAPOL_MESSAGE_TYPE, sizeof(u32),
1019 (u8 *)&eapol_msg_type, pTlv);
1020 tot_len += sizeof(tlv_log) + sizeof(u32);
1021 pTlv = addLoggerTlv(WIFI_TAG_ADDR1, sizeof(pWlanEapolEvent->dest_addr),
1022 (u8 *)pWlanEapolEvent->dest_addr, pTlv);
1023 tot_len += sizeof(tlv_log) + sizeof(pWlanEapolEvent->dest_addr);
1024 pTlv = addLoggerTlv(WIFI_TAG_ADDR2, sizeof(pWlanEapolEvent->src_addr),
1025 (u8 *)pWlanEapolEvent->src_addr, pTlv);
1026 tot_len += sizeof(tlv_log) + sizeof(pWlanEapolEvent->src_addr);
1027
1028 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
1029 if (status != WIFI_SUCCESS) {
1030 ALOGE("Failed to write eapol event into ring buffer");
1031 }
1032
1033 return status;
1034 }
1035
process_wakelock_event(hal_info * info,u8 * buf,int length)1036 static wifi_error process_wakelock_event(hal_info *info, u8* buf, int length)
1037 {
1038 wlan_wake_lock_event_t *pWlanWakeLockEvent;
1039 wake_lock_event *pWakeLockEvent;
1040 wifi_power_event *pPowerEvent;
1041 tlv_log *pTlv;
1042 wifi_ring_buffer_entry *pRingBufferEntry;
1043 u16 len_ring_buffer_entry;
1044 struct timeval time;
1045 wifi_error status;
1046 u8 wl_ring_buffer[RING_BUF_ENTRY_SIZE];
1047 u16 entry_size;
1048
1049 pWlanWakeLockEvent = (wlan_wake_lock_event_t *)(buf);
1050 entry_size = sizeof(wifi_power_event) +
1051 sizeof(tlv_log) +
1052 sizeof(wake_lock_event) +
1053 pWlanWakeLockEvent->name_len + 1;
1054 len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry) + entry_size;
1055
1056 if (len_ring_buffer_entry > RING_BUF_ENTRY_SIZE) {
1057 pRingBufferEntry = (wifi_ring_buffer_entry *)malloc(
1058 len_ring_buffer_entry);
1059 if (pRingBufferEntry == NULL) {
1060 ALOGE("%s: Failed to allocate memory", __FUNCTION__);
1061 return WIFI_ERROR_OUT_OF_MEMORY;
1062 }
1063 } else {
1064 pRingBufferEntry = (wifi_ring_buffer_entry *)wl_ring_buffer;
1065 }
1066
1067 pPowerEvent = (wifi_power_event *)(pRingBufferEntry + 1);
1068 pPowerEvent->event = WIFI_TAG_WAKE_LOCK_EVENT;
1069
1070 pTlv = &pPowerEvent->tlvs[0];
1071 pTlv->tag = WIFI_TAG_WAKE_LOCK_EVENT;
1072 pTlv->length = sizeof(wake_lock_event) +
1073 pWlanWakeLockEvent->name_len + 1;
1074
1075 pWakeLockEvent = (wake_lock_event *)pTlv->value;
1076 pWakeLockEvent->status = pWlanWakeLockEvent->status;
1077 pWakeLockEvent->reason = pWlanWakeLockEvent->reason;
1078 memcpy(pWakeLockEvent->name, pWlanWakeLockEvent->name,
1079 pWlanWakeLockEvent->name_len);
1080
1081 pRingBufferEntry->entry_size = entry_size;
1082 pRingBufferEntry->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY |
1083 RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
1084 pRingBufferEntry->type = ENTRY_TYPE_POWER_EVENT;
1085 gettimeofday(&time, NULL);
1086 pRingBufferEntry->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
1087
1088 /* Write if verbose and handler is set */
1089 if (info->rb_infos[POWER_EVENTS_RB_ID].verbose_level >= 1 &&
1090 info->on_ring_buffer_data) {
1091 status = ring_buffer_write(&info->rb_infos[POWER_EVENTS_RB_ID],
1092 (u8*)pRingBufferEntry,
1093 len_ring_buffer_entry,
1094 1,
1095 len_ring_buffer_entry);
1096 } else {
1097 status = WIFI_SUCCESS;
1098 }
1099
1100 if ((u8 *)pRingBufferEntry != wl_ring_buffer) {
1101 ALOGI("Message with more than RING_BUF_ENTRY_SIZE");
1102 free(pRingBufferEntry);
1103 }
1104
1105 return status;
1106 }
1107
process_wlan_log_complete_event(hal_info * info,u8 * buf,int length)1108 static void process_wlan_log_complete_event(hal_info *info,
1109 u8* buf,
1110 int length)
1111 {
1112 wlan_log_complete_event_t *lfd_event;
1113
1114 ALOGV("Received log completion event from driver");
1115 lfd_event = (wlan_log_complete_event_t *)buf;
1116
1117 push_out_all_ring_buffers(info);
1118
1119 if (lfd_event->is_fatal == WLAN_LOG_TYPE_FATAL) {
1120 ALOGE("Received fatal event, sending alert");
1121 send_alert(info, lfd_event->reason_code);
1122 }
1123 }
1124
update_stats_to_ring_buf(hal_info * info,u8 * rb_entry,u32 size)1125 static wifi_error update_stats_to_ring_buf(hal_info *info,
1126 u8 *rb_entry, u32 size)
1127 {
1128 int num_records = 1;
1129 wifi_ring_buffer_entry *pRingBufferEntry =
1130 (wifi_ring_buffer_entry *)rb_entry;
1131 struct timeval time;
1132
1133 pRingBufferEntry->entry_size = size - sizeof(wifi_ring_buffer_entry);
1134 pRingBufferEntry->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY |
1135 RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
1136 pRingBufferEntry->type = ENTRY_TYPE_PKT;
1137 gettimeofday(&time,NULL);
1138 pRingBufferEntry->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
1139
1140 // Write if verbose and handler is set
1141 if ((info->rb_infos[PKT_STATS_RB_ID].verbose_level >= VERBOSE_DEBUG_PROBLEM)
1142 && info->on_ring_buffer_data) {
1143 ring_buffer_write(&info->rb_infos[PKT_STATS_RB_ID],
1144 (u8*)pRingBufferEntry,
1145 size,
1146 num_records,
1147 size);
1148 }
1149
1150 return WIFI_SUCCESS;
1151 }
1152
get_rate(u16 mcs_r)1153 static u16 get_rate(u16 mcs_r)
1154 {
1155 u16 tx_rate = 0;
1156 MCS mcs;
1157 static u16 rate_lookup[][8] = {{96, 48, 24, 12, 108, 72, 36, 18},
1158 {22, 11, 4, 2, 22, 11, 4, 0}};
1159 static u16 MCS_rate_lookup_ht[][8] =
1160 {{ 13, 14, 27, 30, 59, 65, 117, 130},
1161 { 26, 29, 54, 60, 117, 130, 234, 260},
1162 { 39, 43, 81, 90, 176, 195, 351, 390},
1163 { 52, 58, 108, 120, 234, 260, 468, 520},
1164 { 78, 87, 162, 180, 351, 390, 702, 780},
1165 {104, 116, 216, 240, 468, 520, 936, 1040},
1166 {117, 130, 243, 270, 527, 585, 1053, 1170},
1167 {130, 144, 270, 300, 585, 650, 1170, 1300},
1168 {156, 173, 324, 360, 702, 780, 1404, 1560},
1169 { 0, 0, 360, 400, 780, 867, 1560, 1733},
1170 { 26, 29, 54, 60, 117, 130, 234, 260},
1171 { 52, 58, 108, 120, 234, 260, 468, 520},
1172 { 78, 87, 162, 180, 351, 390, 702, 780},
1173 {104, 116, 216, 240, 468, 520, 936, 1040},
1174 {156, 173, 324, 360, 702, 780, 1404, 1560},
1175 {208, 231, 432, 480, 936,1040, 1872, 2080},
1176 {234, 261, 486, 540,1053,1170, 2106, 2340},
1177 {260, 289, 540, 600,1170,1300, 2340, 2600},
1178 {312, 347, 648, 720,1404,1560, 2808, 3120},
1179 { 0, 0, 720, 800,1560,1733, 3120, 3467}};
1180
1181 mcs.mcs = mcs_r;
1182 if ((mcs.mcs_s.preamble <= WL_PREAMBLE_VHT) && (mcs.mcs_s.rate < 10)) {
1183 switch(mcs.mcs_s.preamble)
1184 {
1185 case WL_PREAMBLE_CCK:
1186 case WL_PREAMBLE_OFDM:
1187 if(mcs.mcs_s.rate<8) {
1188 tx_rate = rate_lookup [mcs.mcs_s.preamble][mcs.mcs_s.rate];
1189 if (mcs.mcs_s.nss)
1190 tx_rate *=2;
1191 } else {
1192 ALOGE("Unexpected rate value");
1193 }
1194 break;
1195 case WL_PREAMBLE_HT:
1196 if(mcs.mcs_s.rate<8) {
1197 if (!mcs.mcs_s.nss)
1198 tx_rate = MCS_rate_lookup_ht[mcs.mcs_s.rate]
1199 [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi];
1200 else
1201 tx_rate = MCS_rate_lookup_ht[10+mcs.mcs_s.rate]
1202 [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi];
1203 } else {
1204 ALOGE("Unexpected HT mcs.mcs_s index");
1205 }
1206 break;
1207 case WL_PREAMBLE_VHT:
1208 if (!mcs.mcs_s.nss)
1209 tx_rate = MCS_rate_lookup_ht[mcs.mcs_s.rate]
1210 [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi];
1211 else
1212 tx_rate = MCS_rate_lookup_ht[10+mcs.mcs_s.rate]
1213 [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi];
1214 break;
1215 default:
1216 ALOGE("Unexpected preamble");
1217 }
1218 }
1219 return tx_rate;
1220 }
1221
populate_rx_aggr_stats(hal_info * info)1222 static wifi_error populate_rx_aggr_stats(hal_info *info)
1223 {
1224 wifi_error status;
1225 wifi_ring_buffer_entry *pRingBufferEntry = info->rx_aggr_pkts;
1226 wifi_ring_per_packet_status_entry *pps_entry;
1227 u32 index = 0;
1228
1229 while (index < info->rx_buf_size_occupied) {
1230 pps_entry = (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
1231
1232 pps_entry->MCS = info->aggr_stats.RxMCS.mcs;
1233 pps_entry->last_transmit_rate = info->aggr_stats.last_transmit_rate;
1234 pps_entry->rssi = info->aggr_stats.rssi;
1235 pps_entry->firmware_entry_timestamp = info->aggr_stats.timestamp;
1236 pps_entry->tid = info->aggr_stats.tid;
1237
1238 index += pRingBufferEntry->entry_size;
1239 status = update_stats_to_ring_buf(info, (u8 *)pRingBufferEntry,
1240 pRingBufferEntry->entry_size);
1241
1242 if (status != WIFI_SUCCESS) {
1243 ALOGE("Failed to write Rx stats into the ring buffer");
1244 return status;
1245 }
1246 /* update_stats_to_ring_buf() modifies the size. Update the same again
1247 * here by adding sizeof(wifi_ring_buffer_entry) to continue parsing
1248 */
1249 pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)pRingBufferEntry
1250 + sizeof(wifi_ring_buffer_entry)
1251 + pRingBufferEntry->entry_size);
1252 }
1253 memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied);
1254 info->rx_buf_size_occupied = 0;
1255
1256 return WIFI_SUCCESS;
1257 }
1258
parse_rx_stats(hal_info * info,u8 * buf,u16 size)1259 static wifi_error parse_rx_stats(hal_info *info, u8 *buf, u16 size)
1260 {
1261 wifi_error status;
1262 rb_pkt_stats_t *rx_stats_rcvd = (rb_pkt_stats_t *)buf;
1263 wifi_ring_buffer_entry *pRingBufferEntry;
1264 u32 len_ring_buffer_entry = 0;
1265
1266 if (size < sizeof(rb_pkt_stats_t)) {
1267 ALOGE("%s Unexpected rx stats event length: %d", __FUNCTION__, size);
1268 memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied);
1269 memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats));
1270 info->rx_buf_size_occupied = 0;
1271 return WIFI_ERROR_UNKNOWN;
1272 }
1273
1274 len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry)
1275 + sizeof(wifi_ring_per_packet_status_entry)
1276 + RX_HTT_HDR_STATUS_LEN;
1277
1278 if (len_ring_buffer_entry + info->rx_buf_size_occupied
1279 > info->rx_buf_size_allocated) {
1280 wifi_ring_buffer_entry *temp;
1281 temp = (wifi_ring_buffer_entry *)realloc(info->rx_aggr_pkts,
1282 len_ring_buffer_entry + info->rx_buf_size_occupied);
1283 if (temp == NULL) {
1284 ALOGE("%s: Failed to reallocate memory", __FUNCTION__);
1285 free(info->rx_aggr_pkts);
1286 info->rx_aggr_pkts = NULL;
1287 return WIFI_ERROR_OUT_OF_MEMORY;
1288 }
1289 info->rx_aggr_pkts = temp;
1290 memset((u8 *)info->rx_aggr_pkts + info->rx_buf_size_allocated, 0,
1291 len_ring_buffer_entry + info->rx_buf_size_occupied
1292 - info->rx_buf_size_allocated);
1293 info->rx_buf_size_allocated =
1294 len_ring_buffer_entry + info->rx_buf_size_occupied;
1295 }
1296
1297 pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)info->rx_aggr_pkts
1298 + info->rx_buf_size_occupied);
1299
1300 info->rx_buf_size_occupied += len_ring_buffer_entry;
1301
1302 /* Fill size of the entry in rb entry which can be used while populating
1303 * the data. Actual size that needs to be sent to ring buffer is only pps
1304 * entry size
1305 */
1306 pRingBufferEntry->entry_size = len_ring_buffer_entry;
1307 wifi_ring_per_packet_status_entry *rb_pkt_stats =
1308 (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
1309
1310 memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry));
1311
1312 /* Peer tx packet and it is an Rx packet for us */
1313 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_DIRECTION_TX;
1314
1315 if (!((rx_stats_rcvd->mpdu_end.overflow_err) ||
1316 (rx_stats_rcvd->attention.fcs_err) ||
1317 (rx_stats_rcvd->attention.mpdu_length_err) ||
1318 (rx_stats_rcvd->attention.msdu_length_err) ||
1319 (rx_stats_rcvd->attention.tkip_mic_err) ||
1320 (rx_stats_rcvd->attention.decrypt_err)))
1321 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
1322
1323 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER;
1324
1325 if (rx_stats_rcvd->mpdu_start.encrypted)
1326 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED;
1327
1328 if (rx_stats_rcvd->attention.first_mpdu) {
1329 MCS *mcs = &info->aggr_stats.RxMCS;
1330 u32 ht_vht_sig;
1331
1332 /* Flush the cached stats as this is the first MPDU. */
1333 memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats));
1334 if (rx_stats_rcvd->ppdu_start.preamble_type == PREAMBLE_L_SIG_RATE) {
1335 if (rx_stats_rcvd->ppdu_start.l_sig_rate_select)
1336 mcs->mcs_s.preamble = WL_PREAMBLE_OFDM;
1337 mcs->mcs_s.rate = rx_stats_rcvd->ppdu_start.l_sig_rate - 8;
1338 /*BW is 0 for legacy cases*/
1339 } else if (rx_stats_rcvd->ppdu_start.preamble_type ==
1340 PREAMBLE_VHT_SIG_A_1) {
1341 ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1;
1342 mcs->mcs_s.nss = ((ht_vht_sig >> 3) & 0x3);
1343 mcs->mcs_s.preamble = WL_PREAMBLE_HT;
1344 mcs->mcs_s.rate = (ht_vht_sig & BITMASK(7)) >> 3;
1345 mcs->mcs_s.bw = ((ht_vht_sig >> 7) & 1);
1346 mcs->mcs_s.short_gi =
1347 ((rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 7) & 1);
1348 } else if (rx_stats_rcvd->ppdu_start.preamble_type ==
1349 PREAMBLE_VHT_SIG_A_2) {
1350 ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1;
1351 mcs->mcs_s.nss = ((ht_vht_sig >> 10) & 0x3);
1352 mcs->mcs_s.preamble = WL_PREAMBLE_VHT;
1353 mcs->mcs_s.rate =
1354 (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 4) & BITMASK(4);
1355 mcs->mcs_s.bw = (ht_vht_sig & 3);
1356 mcs->mcs_s.short_gi =
1357 (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 & 1);
1358 }
1359
1360 info->aggr_stats.last_transmit_rate
1361 = get_rate(info->aggr_stats.RxMCS.mcs);
1362
1363 info->aggr_stats.rssi = rx_stats_rcvd->ppdu_start.rssi_comb;
1364 info->aggr_stats.tid = rx_stats_rcvd->mpdu_start.tid;
1365 }
1366 rb_pkt_stats->link_layer_transmit_sequence
1367 = rx_stats_rcvd->mpdu_start.seq_num;
1368
1369 memcpy(&rb_pkt_stats->data[0], &rx_stats_rcvd->rx_hdr_status[0],
1370 RX_HTT_HDR_STATUS_LEN);
1371
1372 if ((rx_stats_rcvd->attention.last_mpdu
1373 && rx_stats_rcvd->msdu_end.last_msdu)
1374 || (rx_stats_rcvd->attention.first_mpdu
1375 && rx_stats_rcvd->attention.last_mpdu)) {
1376 info->aggr_stats.timestamp = rx_stats_rcvd->ppdu_end.tsf_timestamp;
1377 status = populate_rx_aggr_stats(info);
1378 }
1379
1380 return status;
1381 }
1382
get_tx_mcs(u8 series,struct tx_ppdu_start * ppdu_start)1383 static u16 get_tx_mcs(u8 series,
1384 struct tx_ppdu_start *ppdu_start)
1385 {
1386 u16 tx_rate = 0;
1387 MCS mcs;
1388 struct series_bw *sbw = NULL;
1389
1390 mcs.mcs = 0;
1391
1392 if (series == 0) {
1393 if (ppdu_start->valid_s0_bw20)
1394 sbw = &ppdu_start->s0_bw20;
1395 else if (ppdu_start->valid_s0_bw40)
1396 sbw = &ppdu_start->s0_bw40;
1397 else if (ppdu_start->valid_s0_bw80)
1398 sbw = &ppdu_start->s0_bw80;
1399 else if (ppdu_start->valid_s0_bw160)
1400 sbw = &ppdu_start->s0_bw160;
1401 } else {
1402 if (ppdu_start->valid_s1_bw20)
1403 sbw = &ppdu_start->s1_bw20;
1404 else if (ppdu_start->valid_s1_bw40)
1405 sbw = &ppdu_start->s1_bw40;
1406 else if (ppdu_start->valid_s1_bw80)
1407 sbw = &ppdu_start->s1_bw80;
1408 else if (ppdu_start->valid_s1_bw160)
1409 sbw = &ppdu_start->s1_bw160;
1410 }
1411
1412 if (sbw) {
1413 mcs.mcs_s.rate = sbw->rate;
1414 mcs.mcs_s.nss = sbw->nss;
1415 mcs.mcs_s.preamble = sbw->preamble_type;
1416 mcs.mcs_s.short_gi = sbw->short_gi;
1417 }
1418
1419 return mcs.mcs;
1420 }
1421
get_tx_aggr_stats(struct tx_ppdu_start * ppdu_start,hal_info * info)1422 static void get_tx_aggr_stats(struct tx_ppdu_start *ppdu_start, hal_info *info)
1423 {
1424 u32 baBitmap0 = 0;
1425 u32 baBitmap1 = 0;
1426
1427 info->pkt_stats->tx_seqnum_bitmap_31_0 = ppdu_start->seqnum_bitmap_31_0;
1428 info->pkt_stats->tx_seqnum_bitmap_63_32 = ppdu_start->seqnum_bitmap_63_32;
1429
1430 if (info->pkt_stats->isBlockAck) {
1431 int baShift = ppdu_start->start_seq_num - info->pkt_stats->ba_seq_num;
1432 //There are 4 scenarios in total:
1433 //1.TxSeq No. >= BaSeq No. and no roll over.
1434 //2.TxSeq No. >= BaSeq No. and TxSeq No. rolls over.
1435 //3.TxSeq No. <= BaSeq No. and no roll over.
1436 //4.TxSeq No. <= BaSeq No. and BaSeq No. rolls over.
1437
1438 baBitmap0 = info->pkt_stats->ba_bitmap_31_0;
1439 baBitmap1 = info->pkt_stats->ba_bitmap_63_32;
1440
1441 if (((baShift >= 0) && (baShift < SEQ_NUM_RANGE/2)) ||
1442 (baShift < -SEQ_NUM_RANGE/2)) {
1443 //Scenario No.1 and No.2
1444 baShift = baShift < -SEQ_NUM_RANGE/2 ? (SEQ_NUM_RANGE + baShift) :
1445 baShift;
1446
1447 if (baShift < BITMAP_VAR_SIZE) {
1448 info->pkt_stats->shifted_bitmap_31_0 =
1449 ((baBitmap1 << (32 - baShift)) | (baBitmap0 >> baShift));
1450 info->pkt_stats->shifted_bitmap_63_32 = baBitmap1 >> baShift;
1451 } else {
1452 info->pkt_stats->shifted_bitmap_31_0 =
1453 baBitmap1 >> (baShift - BITMAP_VAR_SIZE);
1454 info->pkt_stats->shifted_bitmap_63_32 = 0;
1455 }
1456 } else {
1457 baShift = (baShift >= SEQ_NUM_RANGE/2) ? (SEQ_NUM_RANGE - baShift) :
1458 -baShift;
1459 if (baShift < BITMAP_VAR_SIZE) {
1460 info->pkt_stats->shifted_bitmap_31_0 = baBitmap0 << baShift;
1461 info->pkt_stats->shifted_bitmap_63_32 =
1462 ((baBitmap0 << (32 - baShift)) |
1463 (baBitmap1 >> baShift));
1464 } else {
1465 info->pkt_stats->shifted_bitmap_31_0 = 0;
1466 info->pkt_stats->shifted_bitmap_63_32 =
1467 baBitmap0 << (baShift - BITMAP_VAR_SIZE);
1468 }
1469 }
1470 } else {
1471 info->pkt_stats->shifted_bitmap_31_0 = 0;
1472 info->pkt_stats->shifted_bitmap_63_32 = 0;
1473 }
1474 }
1475
get_try_status_params(hal_info * info,struct tx_ppdu_end * tx_ppdu_end)1476 static void get_try_status_params(hal_info *info,
1477 struct tx_ppdu_end *tx_ppdu_end)
1478 {
1479 int try_list_index;
1480
1481 if (tx_ppdu_end->stat.total_tries > 0)
1482 try_list_index = tx_ppdu_end->stat.total_tries - 1;
1483 else
1484 try_list_index = 0;
1485
1486 info->pkt_stats->tx_bandwidth =
1487 tx_ppdu_end->try_list.try_st[try_list_index].packet_bw;
1488 info->pkt_stats->series =
1489 tx_ppdu_end->try_list.try_st[try_list_index].series;
1490 }
1491
parse_tx_stats(hal_info * info,void * buf,u32 buflen,u8 logtype)1492 static wifi_error parse_tx_stats(hal_info *info, void *buf,
1493 u32 buflen, u8 logtype)
1494 {
1495 wifi_error status = WIFI_SUCCESS;
1496 int i;
1497 wifi_ring_buffer_entry *pRingBufferEntry =
1498 (wifi_ring_buffer_entry *)info->pkt_stats->tx_stats;
1499
1500 wifi_ring_per_packet_status_entry *rb_pkt_stats =
1501 (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
1502
1503 ALOGV("Received Tx stats: log_type : %d", logtype);
1504 switch (logtype)
1505 {
1506 case PKTLOG_TYPE_TX_CTRL:
1507 {
1508 if (buflen < sizeof (wh_pktlog_txctl)) {
1509 ALOGE("Unexpected tx_ctrl event length: %d", buflen);
1510 return WIFI_ERROR_UNKNOWN;
1511 }
1512
1513 wh_pktlog_txctl *stats = (wh_pktlog_txctl *)buf;
1514 struct tx_ppdu_start *ppdu_start =
1515 (struct tx_ppdu_start *)(&stats->u.ppdu_start);
1516
1517 if (ppdu_start->frame_control & BIT(DATA_PROTECTED))
1518 rb_pkt_stats->flags |=
1519 PER_PACKET_ENTRY_FLAGS_PROTECTED;
1520 rb_pkt_stats->link_layer_transmit_sequence
1521 = ppdu_start->start_seq_num;
1522 info->pkt_stats->start_seq_num = ppdu_start->start_seq_num;
1523 rb_pkt_stats->tid = ppdu_start->qos_ctl & 0xF;
1524 rb_pkt_stats->MCS = get_tx_mcs(info->pkt_stats->series, ppdu_start) |
1525 (info->pkt_stats->tx_bandwidth << BW_OFFSET);
1526 rb_pkt_stats->last_transmit_rate = get_rate(rb_pkt_stats->MCS);
1527
1528 if (ppdu_start->ampdu)
1529 get_tx_aggr_stats(ppdu_start, info);
1530 info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_CTRL);
1531 }
1532 break;
1533 case PKTLOG_TYPE_TX_STAT:
1534 {
1535 if (buflen < sizeof(struct tx_ppdu_end)) {
1536 ALOGE("Unexpected tx_stat event length: %d", buflen);
1537 return WIFI_ERROR_UNKNOWN;
1538 }
1539
1540 /* This should be the first event for tx-stats: So,
1541 * previous stats are invalid. Flush the old stats and treat
1542 * this as new packet
1543 */
1544 if (info->pkt_stats->tx_stats_events)
1545 memset(rb_pkt_stats, 0,
1546 sizeof(wifi_ring_per_packet_status_entry));
1547
1548 struct tx_ppdu_end *tx_ppdu_end = (struct tx_ppdu_end*)(buf);
1549
1550 info->pkt_stats->ba_seq_num = tx_ppdu_end->stat.ba_start_seq_num;
1551 info->pkt_stats->isBlockAck = tx_ppdu_end->stat.ba_status;
1552
1553 if (tx_ppdu_end->stat.tx_ok)
1554 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
1555 info->pkt_stats->isBlockAck = tx_ppdu_end->stat.ba_status;
1556
1557 info->pkt_stats->ba_bitmap_31_0 = tx_ppdu_end->stat.ba_bitmap_31_0;
1558 info->pkt_stats->ba_bitmap_63_32 =
1559 tx_ppdu_end->stat.ba_bitmap_63_32;
1560 rb_pkt_stats->transmit_success_timestamp =
1561 tx_ppdu_end->try_list.try_st[0].timestamp;
1562 rb_pkt_stats->rssi = tx_ppdu_end->stat.ack_rssi_ave;
1563 rb_pkt_stats->num_retries = tx_ppdu_end->stat.total_tries;
1564 get_try_status_params(info, tx_ppdu_end);
1565
1566 info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_STAT);
1567 }
1568 break;
1569 case PKTLOG_TYPE_TX_MSDU_ID:
1570 {
1571 memset(info->pkt_stats, 0, sizeof(struct pkt_stats_s));
1572 info->pkt_stats->num_msdu = *(u8 *)buf;
1573 info->pkt_stats->tx_stats_events = BIT(PKTLOG_TYPE_TX_MSDU_ID);
1574 }
1575 break;
1576 case PKTLOG_TYPE_RC_UPDATE:
1577 case PKTLOG_TYPE_TX_FRM_HDR:
1578 case PKTLOG_TYPE_RC_FIND:
1579 case PKTLOG_TYPE_TX_VIRT_ADDR:
1580 ALOGV("%s : Unsupported log_type received : %d",
1581 __FUNCTION__, logtype);
1582 break;
1583 default:
1584 {
1585 ALOGV("%s : Unexpected log_type received : %d",
1586 __FUNCTION__, logtype);
1587 return WIFI_ERROR_UNKNOWN;
1588 }
1589 }
1590
1591 if ((info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_CTRL)) &&
1592 (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_STAT)) &&
1593 (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_MSDU_ID))) {
1594 /* No tx payload as of now, add the length to parameter size(3rd)
1595 * if there is any payload
1596 */
1597
1598 if (info->pkt_stats->num_msdu == 1) {
1599 if (!(rb_pkt_stats->flags & PER_PACKET_ENTRY_FLAGS_TX_SUCCESS))
1600 rb_pkt_stats->rssi = INVALID_RSSI;
1601 /* Handle non aggregated cases */
1602 status = update_stats_to_ring_buf(info,
1603 (u8 *)pRingBufferEntry,
1604 sizeof(wifi_ring_buffer_entry) +
1605 sizeof(wifi_ring_per_packet_status_entry));
1606 if (status != WIFI_SUCCESS) {
1607 ALOGE("Failed to write into the ring buffer : %d", logtype);
1608 }
1609 } else {
1610 /* Handle aggregated cases */
1611 for (i = 0; i < MAX_BA_WINDOW_SIZE; i++) {
1612 if (i < BITMAP_VAR_SIZE) {
1613 if (info->pkt_stats->tx_seqnum_bitmap_31_0 & BIT(i)) {
1614 if (info->pkt_stats->shifted_bitmap_31_0 & BIT(i)) {
1615 rb_pkt_stats->flags |=
1616 PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
1617 } else {
1618 rb_pkt_stats->flags &=
1619 ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
1620 rb_pkt_stats->rssi = INVALID_RSSI;
1621 }
1622 } else {
1623 continue;
1624 }
1625 } else {
1626 if (info->pkt_stats->tx_seqnum_bitmap_63_32
1627 & BIT(i - BITMAP_VAR_SIZE)) {
1628 if (info->pkt_stats->shifted_bitmap_63_32
1629 & BIT(i - BITMAP_VAR_SIZE)) {
1630 rb_pkt_stats->flags |=
1631 PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
1632 } else {
1633 rb_pkt_stats->flags &=
1634 ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
1635 rb_pkt_stats->rssi = INVALID_RSSI;
1636 }
1637 } else {
1638 continue;
1639 }
1640 }
1641 rb_pkt_stats->link_layer_transmit_sequence =
1642 info->pkt_stats->start_seq_num + i;
1643
1644 /* Take care of roll over SEQ_NUM_RANGE */
1645 rb_pkt_stats->link_layer_transmit_sequence &= 0xFFF;
1646
1647 status = update_stats_to_ring_buf(info,
1648 (u8 *)pRingBufferEntry,
1649 sizeof(wifi_ring_buffer_entry) +
1650 sizeof(wifi_ring_per_packet_status_entry));
1651 if (status != WIFI_SUCCESS) {
1652 ALOGE("Failed to write into the ring buffer: %d", logtype);
1653 break;
1654 }
1655 }
1656 }
1657
1658 /* Flush the local copy after writing the stats to ring buffer
1659 * for tx-stats.
1660 */
1661 info->pkt_stats->tx_stats_events = 0;
1662 memset(rb_pkt_stats, 0,
1663 sizeof(wifi_ring_per_packet_status_entry));
1664
1665 }
1666
1667 return status;
1668 }
1669
parse_stats_record(hal_info * info,wh_pktlog_hdr_t * pkt_stats_header)1670 static wifi_error parse_stats_record(hal_info *info,
1671 wh_pktlog_hdr_t *pkt_stats_header)
1672 {
1673 wifi_error status;
1674 if (pkt_stats_header->log_type == PKTLOG_TYPE_RX_STAT) {
1675 /* Ignore the event if it doesn't carry RX descriptor */
1676 if (pkt_stats_header->flags & PKT_INFO_FLG_RX_RXDESC_MASK)
1677 status = parse_rx_stats(info,
1678 (u8 *)(pkt_stats_header + 1),
1679 pkt_stats_header->size);
1680 else
1681 status = WIFI_SUCCESS;
1682 } else {
1683 status = parse_tx_stats(info,
1684 (u8 *)(pkt_stats_header + 1),
1685 pkt_stats_header->size,
1686 pkt_stats_header->log_type);
1687 }
1688 return status;
1689 }
1690
parse_stats(hal_info * info,u8 * data,u32 buflen)1691 static wifi_error parse_stats(hal_info *info, u8 *data, u32 buflen)
1692 {
1693 wh_pktlog_hdr_t *pkt_stats_header;
1694 wifi_error status = WIFI_SUCCESS;
1695
1696 do {
1697 if (buflen < sizeof(wh_pktlog_hdr_t)) {
1698 status = WIFI_ERROR_INVALID_ARGS;
1699 break;
1700 }
1701
1702 pkt_stats_header = (wh_pktlog_hdr_t *)data;
1703
1704 if (buflen < (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size)) {
1705 status = WIFI_ERROR_INVALID_ARGS;
1706 break;
1707 }
1708 status = parse_stats_record(info, pkt_stats_header);
1709 if (status != WIFI_SUCCESS) {
1710 ALOGE("Failed to parse the stats type : %d",
1711 pkt_stats_header->log_type);
1712 return status;
1713 }
1714 data += (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size);
1715 buflen -= (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size);
1716 } while (buflen > 0);
1717
1718 return status;
1719 }
1720
process_driver_prints(hal_info * info,u8 * buf,u16 length)1721 wifi_error process_driver_prints(hal_info *info, u8 *buf, u16 length)
1722 {
1723 wifi_ring_buffer_entry rb_entry_hdr;
1724 struct timeval time;
1725 wifi_error status;
1726
1727 rb_entry_hdr.entry_size = length;
1728 rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
1729 rb_entry_hdr.type = ENTRY_TYPE_DATA;
1730 gettimeofday(&time, NULL);
1731 rb_entry_hdr.timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
1732
1733 /* Write if verbose and handler is set */
1734 if (info->rb_infos[DRIVER_PRINTS_RB_ID].verbose_level >= 1 &&
1735 info->on_ring_buffer_data) {
1736 /* Write header and payload separately to avoid
1737 * complete payload memcpy */
1738 status = ring_buffer_write(&info->rb_infos[DRIVER_PRINTS_RB_ID],
1739 (u8*)&rb_entry_hdr,
1740 sizeof(wifi_ring_buffer_entry),
1741 0,
1742 sizeof(wifi_ring_buffer_entry) + length);
1743 if (status != WIFI_SUCCESS) {
1744 ALOGE("Failed to write driver prints rb header %d", status);
1745 return status;
1746 }
1747 status = ring_buffer_write(&info->rb_infos[DRIVER_PRINTS_RB_ID],
1748 buf, length, 1, length);
1749 if (status != WIFI_SUCCESS) {
1750 ALOGE("Failed to write driver prints rb payload %d", status);
1751 return status;
1752 }
1753 }
1754
1755 return WIFI_SUCCESS;
1756 }
1757
diag_message_handler(hal_info * info,nl_msg * msg)1758 wifi_error diag_message_handler(hal_info *info, nl_msg *msg)
1759 {
1760 tAniNlHdr *wnl = (tAniNlHdr *)nlmsg_hdr(msg);
1761 u8 *buf;
1762 wifi_error status;
1763
1764 /* Check nlmsg_type also to avoid processing unintended msgs */
1765 if (wnl->nlh.nlmsg_type == ANI_NL_MSG_PUMAC) {
1766 if (wnl->wmsg.type == ANI_NL_MSG_LOG_HOST_EVENT_LOG_TYPE) {
1767 uint32_t diag_host_type;
1768
1769 buf = (uint8_t *)(wnl + 1);
1770 diag_host_type = *(uint32_t *)(buf);
1771 ALOGV("diag type = %d", diag_host_type);
1772
1773 buf += sizeof(uint32_t); //diag_type
1774 if (diag_host_type == DIAG_TYPE_HOST_EVENTS) {
1775 host_event_hdr_t *event_hdr =
1776 (host_event_hdr_t *)(buf);
1777 ALOGV("diag event_id = %x length %d",
1778 event_hdr->event_id, event_hdr->length);
1779 buf += sizeof(host_event_hdr_t);
1780 switch (event_hdr->event_id) {
1781 case EVENT_WLAN_WAKE_LOCK:
1782 process_wakelock_event(info, buf, event_hdr->length);
1783 break;
1784 case EVENT_WLAN_PE:
1785 process_wlan_pe_event(info, buf, event_hdr->length);
1786 break;
1787 case EVENT_WLAN_EAPOL:
1788 process_wlan_eapol_event(info, buf, event_hdr->length);
1789 break;
1790 case EVENT_WLAN_LOG_COMPLETE:
1791 process_wlan_log_complete_event(info, buf, event_hdr->length);
1792 break;
1793 default:
1794 return WIFI_SUCCESS;
1795 }
1796 } else if (diag_host_type == DIAG_TYPE_HOST_LOG_MSGS) {
1797 drv_msg_t *drv_msg = (drv_msg_t *) (buf);
1798 ALOGV("diag event_type = %0x length = %d",
1799 drv_msg->event_type, drv_msg->length);
1800 if (drv_msg->event_type == WLAN_PKT_LOG_STATS) {
1801 if ((info->prev_seq_no + 1) !=
1802 drv_msg->u.pkt_stats_event.msg_seq_no) {
1803 ALOGE("Few pkt stats messages missed: rcvd = %d, prev = %d",
1804 drv_msg->u.pkt_stats_event.msg_seq_no,
1805 info->prev_seq_no);
1806 if (info->pkt_stats->tx_stats_events) {
1807 info->pkt_stats->tx_stats_events = 0;
1808 memset(&info->pkt_stats->tx_stats, 0,
1809 sizeof(wifi_ring_per_packet_status_entry));
1810 }
1811 }
1812
1813 info->prev_seq_no =
1814 drv_msg->u.pkt_stats_event.msg_seq_no;
1815 status = parse_stats(info,
1816 drv_msg->u.pkt_stats_event.payload,
1817 drv_msg->u.pkt_stats_event.payload_len);
1818 if (status != WIFI_SUCCESS) {
1819 ALOGE("%s: Failed to parse Tx-Rx stats", __FUNCTION__);
1820 ALOGE("Received msg Seq_num : %d",
1821 drv_msg->u.pkt_stats_event.msg_seq_no);
1822 hexdump((char *)drv_msg->u.pkt_stats_event.payload,
1823 drv_msg->u.pkt_stats_event.payload_len);
1824 return status;
1825 }
1826 }
1827 }
1828 }
1829 } else if (wnl->nlh.nlmsg_type == ANI_NL_MSG_LOG) {
1830 if (wnl->wmsg.type == ANI_NL_MSG_LOG_HOST_PRINT_TYPE) {
1831 process_driver_prints(info, (u8 *)(wnl + 1), wnl->wmsg.length);
1832 }
1833 } else if (wnl->nlh.nlmsg_type == ANI_NL_MSG_CNSS_DIAG) {
1834 uint16_t diag_fw_type;
1835 uint32_t event_id;
1836 buf = (uint8_t *)NLMSG_DATA(wnl);
1837
1838 fw_event_hdr_t *event_hdr =
1839 (fw_event_hdr_t *)(buf);
1840 diag_fw_type = event_hdr->diag_type;
1841 if (diag_fw_type == DIAG_TYPE_FW_MSG) {
1842 dbglog_slot *slot;
1843 u16 length = 0;
1844 u32 version = 0;
1845
1846 slot = (dbglog_slot *)buf;
1847 length = get_le32((u8 *)&slot->length);
1848 process_fw_diag_msg(info, &slot->payload[0], length);
1849 }
1850 }
1851 return WIFI_SUCCESS;
1852 }
1853