1 /* Copyright (c) 2015, 2018 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 * Changes from Qualcomm Innovation Center are provided under the following license:
29 *
30 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted (subject to the limitations in the
34 * disclaimer below) provided that the following conditions are met:
35 *
36 * * Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 *
39 * * Redistributions in binary form must reproduce the above
40 * copyright notice, this list of conditions and the following
41 * disclaimer in the documentation and/or other materials provided
42 * with the distribution.
43 *
44 * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
45 * contributors may be used to endorse or promote products derived
46 * from this software without specific prior written permission.
47 *
48 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
49 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
50 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
51 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
52 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
53 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
54 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
56 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
58 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
59 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
60 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 */
62
63 /* Suppress -Waddress-of-packed-member for new toolchain update.
64 * Bug: http://b/33566695
65 */
66 #if __clang_major__ >= 4
67 #pragma clang diagnostic ignored "-Waddress-of-packed-member"
68 #endif
69
70 #include <netlink/genl/genl.h>
71 #include <netlink/genl/family.h>
72 #include <netlink/genl/ctrl.h>
73 #include <linux/rtnetlink.h>
74 #include <netinet/in.h>
75 #include <cld80211_lib.h>
76 #include "wifiloggercmd.h"
77 #include "wifilogger_event_defs.h"
78 #include "wifilogger_diag.h"
79 #include "wifilogger_vendor_tag_defs.h"
80 #include "pkt_stats.h"
81 #include <errno.h>
82 #include "wifi_hal_ctrl.h"
83
get_le32(const uint8_t * pos)84 static uint32_t get_le32(const uint8_t *pos)
85 {
86 return pos[0] | (pos[1] << 8) | (pos[2] << 16) | (pos[3] << 24);
87 }
88
89 #define MAX_CONNECTIVITY_EVENTS 18 // should match the value in wifi_logger.h
90 static event_remap_t events[MAX_CONNECTIVITY_EVENTS] = {
91 {WLAN_PE_DIAG_ASSOC_REQ_EVENT, WIFI_EVENT_ASSOCIATION_REQUESTED},
92 {WLAN_PE_DIAG_AUTH_COMP_EVENT, WIFI_EVENT_AUTH_COMPLETE},
93 {WLAN_PE_DIAG_CONNECTED, WIFI_EVENT_ASSOC_COMPLETE},
94 {WLAN_PE_DIAG_AUTH_START_EVENT, WIFI_EVENT_FW_AUTH_STARTED},
95 {WLAN_PE_DIAG_ASSOC_START_EVENT, WIFI_EVENT_FW_ASSOC_STARTED},
96 {WLAN_PE_DIAG_REASSOC_START_EVENT, WIFI_EVENT_FW_RE_ASSOC_STARTED},
97 {WLAN_PE_DIAG_SCAN_REQ_EVENT, WIFI_EVENT_DRIVER_SCAN_REQUESTED},
98 {WLAN_PE_DIAG_SCAN_RES_FOUND_EVENT, WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND},
99 {WLAN_PE_DIAG_SCAN_COMP_EVENT, WIFI_EVENT_DRIVER_SCAN_COMPLETE},
100 {WLAN_PE_DIAG_DISASSOC_REQ_EVENT, WIFI_EVENT_DISASSOCIATION_REQUESTED},
101 {WLAN_PE_DIAG_ASSOC_REQ_EVENT, WIFI_EVENT_RE_ASSOCIATION_REQUESTED},
102 {WLAN_PE_DIAG_ROAM_AUTH_START_EVENT, WIFI_EVENT_ROAM_AUTH_STARTED},
103 {WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT, WIFI_EVENT_ROAM_AUTH_COMPLETE},
104 {WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT, WIFI_EVENT_ROAM_ASSOC_STARTED},
105 {WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT, WIFI_EVENT_ROAM_ASSOC_COMPLETE},
106 {WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT, WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT},
107 {WLAN_PE_DIAG_ASSOC_TIMEOUT, WIFI_EVENT_ASSOC_TIMEOUT},
108 {WLAN_PE_DIAG_AUTH_TIMEOUT, WIFI_EVENT_AUTH_TIMEOUT},
109 };
110
addLoggerTlv(u16 type,u16 length,u8 * value,tlv_log * pOutTlv)111 tlv_log* addLoggerTlv(u16 type, u16 length, u8* value, tlv_log *pOutTlv)
112 {
113
114 pOutTlv->tag = type;
115 pOutTlv->length = length;
116 memcpy(&pOutTlv->value[0], value, length);
117
118 return((tlv_log *)((u8 *)pOutTlv + sizeof(tlv_log) + length));
119 }
120
add_reason_code_tag(tlv_log ** tlvs,u16 reason_code)121 int add_reason_code_tag(tlv_log **tlvs, u16 reason_code)
122 {
123 *tlvs = addLoggerTlv(WIFI_TAG_REASON_CODE, sizeof(u16),
124 (u8 *)&reason_code, *tlvs);
125 return (sizeof(tlv_log) + sizeof(u16));
126 }
127
add_status_tag(tlv_log ** tlvs,int status)128 int add_status_tag(tlv_log **tlvs, int status)
129 {
130 *tlvs = addLoggerTlv(WIFI_TAG_STATUS, sizeof(int),
131 (u8 *)&status, *tlvs);
132 return (sizeof(tlv_log) + sizeof(int));
133 }
134
update_connectivity_ring_buf(hal_info * info,wifi_ring_buffer_entry * rbe,u32 size)135 static wifi_error update_connectivity_ring_buf(hal_info *info,
136 wifi_ring_buffer_entry *rbe,
137 u32 size)
138 {
139 struct timeval time;
140 u32 total_length = size + sizeof(wifi_ring_buffer_entry);
141
142 rbe->entry_size = size;
143 rbe->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY |
144 RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
145 rbe->type = ENTRY_TYPE_CONNECT_EVENT;
146 gettimeofday(&time,NULL);
147 rbe->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
148
149 /* Write if verbose level and handler are set */
150 if (info->rb_infos[CONNECTIVITY_EVENTS_RB_ID].verbose_level >= 1 &&
151 info->on_ring_buffer_data) {
152 return ring_buffer_write(&info->rb_infos[CONNECTIVITY_EVENTS_RB_ID],
153 (u8*)rbe, total_length, 1, total_length);
154 }
155
156 return WIFI_SUCCESS;
157 }
158
159 #define SCAN_CAP_ENTRY_SIZE 1024
process_log_extscan_capabilities(hal_info * info,u8 * buf,int length)160 static wifi_error process_log_extscan_capabilities(hal_info *info,
161 u8* buf, int length)
162 {
163 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
164 wifi_ring_buffer_entry *pRingBufferEntry;
165 wlan_ext_scan_capabilities_payload_type *pScanCapabilities;
166 wifi_gscan_capabilities gscan_cap;
167 gscan_capabilities_vendor_data_t cap_vendor_data;
168 tlv_log *pTlv;
169 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
170 u8 out_buf[SCAN_CAP_ENTRY_SIZE];
171 wifi_error status;
172
173 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
174 memset(pRingBufferEntry, 0, SCAN_CAP_ENTRY_SIZE);
175 memset(&cap_vendor_data, 0, sizeof(gscan_capabilities_vendor_data_t));
176 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
177 (pRingBufferEntry + 1);
178
179 pConnectEvent->event = WIFI_EVENT_G_SCAN_CAPABILITIES;
180 pTlv = &pConnectEvent->tlvs[0];
181
182 pScanCapabilities = (wlan_ext_scan_capabilities_payload_type *)buf;
183 pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID,
184 sizeof(pScanCapabilities->request_id),
185 (u8 *)&pScanCapabilities->request_id, pTlv);
186 tot_len += sizeof(tlv_log) + sizeof(pScanCapabilities->request_id);
187
188 gscan_cap.max_scan_cache_size =
189 pScanCapabilities->extscan_cache_capabilities.scan_cache_entry_size;
190 gscan_cap.max_scan_buckets =
191 pScanCapabilities->extscan_cache_capabilities.max_buckets;
192 gscan_cap.max_ap_cache_per_scan =
193 pScanCapabilities->extscan_cache_capabilities.max_bssid_per_scan;
194 gscan_cap.max_rssi_sample_size = FEATURE_NOT_SUPPORTED;
195 gscan_cap.max_scan_reporting_threshold =
196 pScanCapabilities->extscan_cache_capabilities.max_table_usage_threshold;
197 gscan_cap.max_hotlist_bssids =
198 pScanCapabilities->extscan_hotlist_monitor_capabilities.max_hotlist_entries;
199 gscan_cap.max_hotlist_ssids =
200 pScanCapabilities->extscan_capabilities.num_extscan_hotlist_ssid;
201 gscan_cap.max_significant_wifi_change_aps = FEATURE_NOT_SUPPORTED;
202 gscan_cap.max_bssid_history_entries = FEATURE_NOT_SUPPORTED;
203 gscan_cap.max_number_epno_networks =
204 pScanCapabilities->extscan_capabilities.num_epno_networks;
205 gscan_cap.max_number_epno_networks_by_ssid =
206 pScanCapabilities->extscan_capabilities.num_epno_networks;
207 gscan_cap.max_number_of_white_listed_ssid =
208 pScanCapabilities->extscan_capabilities.num_roam_ssid_whitelist;
209
210 pTlv = addLoggerTlv(WIFI_TAG_GSCAN_CAPABILITIES,
211 sizeof(wifi_gscan_capabilities),
212 (u8 *)&gscan_cap, pTlv);
213 tot_len += sizeof(tlv_log) + sizeof(wifi_gscan_capabilities);
214
215 cap_vendor_data.hotlist_mon_table_id =
216 pScanCapabilities->extscan_hotlist_monitor_capabilities.table_id;
217 cap_vendor_data.wlan_hotlist_entry_size =
218 pScanCapabilities->extscan_hotlist_monitor_capabilities.wlan_hotlist_entry_size;
219 cap_vendor_data.cache_cap_table_id =
220 pScanCapabilities->extscan_cache_capabilities.table_id;
221 cap_vendor_data.requestor_id =
222 pScanCapabilities->extscan_capabilities.requestor_id;
223 cap_vendor_data.vdev_id =
224 pScanCapabilities->extscan_capabilities.vdev_id;
225 cap_vendor_data.num_extscan_cache_tables =
226 pScanCapabilities->extscan_capabilities.num_extscan_cache_tables;
227 cap_vendor_data.num_wlan_change_monitor_tables =
228 pScanCapabilities->extscan_capabilities.num_wlan_change_monitor_tables;
229 cap_vendor_data.num_hotlist_monitor_tables =
230 pScanCapabilities->extscan_capabilities.num_hotlist_monitor_tables;
231 cap_vendor_data.rtt_one_sided_supported =
232 pScanCapabilities->extscan_capabilities.rtt_one_sided_supported;
233 cap_vendor_data.rtt_11v_supported =
234 pScanCapabilities->extscan_capabilities.rtt_11v_supported;
235 cap_vendor_data.rtt_ftm_supported =
236 pScanCapabilities->extscan_capabilities.rtt_ftm_supported;
237 cap_vendor_data.num_extscan_cache_capabilities =
238 pScanCapabilities->extscan_capabilities.num_extscan_cache_capabilities;
239 cap_vendor_data.num_extscan_wlan_change_capabilities =
240 pScanCapabilities->extscan_capabilities.num_extscan_wlan_change_capabilities;
241 cap_vendor_data.num_extscan_hotlist_capabilities =
242 pScanCapabilities->extscan_capabilities.num_extscan_hotlist_capabilities;
243 cap_vendor_data.num_roam_bssid_blacklist =
244 pScanCapabilities->extscan_capabilities.num_roam_bssid_blacklist;
245 cap_vendor_data.num_roam_bssid_preferred_list =
246 pScanCapabilities->extscan_capabilities.num_roam_bssid_preferred_list;
247
248 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
249 sizeof(gscan_capabilities_vendor_data_t),
250 (u8 *)&cap_vendor_data, pTlv);
251 tot_len += sizeof(tlv_log) + sizeof(gscan_capabilities_vendor_data_t);
252
253 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
254 if (status != WIFI_SUCCESS) {
255 ALOGE("Failed to write ext scan capabilities event into ring buffer");
256 }
257 return status;
258 }
259
process_bt_coex_scan_event(hal_info * info,u32 id,u8 * buf,int length)260 static wifi_error process_bt_coex_scan_event(hal_info *info,
261 u32 id, u8* buf, int length)
262 {
263 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
264 wifi_ring_buffer_entry *pRingBufferEntry;
265 tlv_log *pTlv;
266 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
267 u8 out_buf[RING_BUF_ENTRY_SIZE];
268 wifi_error status;
269
270 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
271 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
272 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
273 (pRingBufferEntry + 1);
274 pTlv = &pConnectEvent->tlvs[0];
275
276 if (id == EVENT_WLAN_BT_COEX_BT_SCAN_START) {
277 wlan_bt_coex_bt_scan_start_payload_type *pBtScanStart;
278 bt_coex_bt_scan_start_vendor_data_t btScanStartVenData;
279
280 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCAN_START;
281
282 pBtScanStart = (wlan_bt_coex_bt_scan_start_payload_type *)buf;
283 btScanStartVenData.scan_type = pBtScanStart->scan_type;
284 btScanStartVenData.scan_bitmap = pBtScanStart->scan_bitmap;
285
286 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
287 sizeof(bt_coex_bt_scan_start_vendor_data_t),
288 (u8 *)&btScanStartVenData, pTlv);
289 tot_len += sizeof(tlv_log) +
290 sizeof(bt_coex_bt_scan_start_vendor_data_t);
291 } else if(id == EVENT_WLAN_BT_COEX_BT_SCAN_STOP) {
292 wlan_bt_coex_bt_scan_stop_payload_type *pBtScanStop;
293 bt_coex_bt_scan_stop_vendor_data_t btScanStopVenData;
294
295 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCAN_STOP;
296
297 pBtScanStop = (wlan_bt_coex_bt_scan_stop_payload_type *)buf;
298 btScanStopVenData.scan_type = pBtScanStop->scan_type;
299 btScanStopVenData.scan_bitmap = pBtScanStop->scan_bitmap;
300
301 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
302 sizeof(bt_coex_bt_scan_stop_vendor_data_t),
303 (u8 *)&btScanStopVenData, pTlv);
304 tot_len += sizeof(tlv_log) + sizeof(bt_coex_bt_scan_stop_vendor_data_t);
305 }
306 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
307 if (status != WIFI_SUCCESS) {
308 ALOGE("Failed to write bt_coex_scan event into ring buffer");
309 }
310
311 return status;
312 }
313
process_bt_coex_event(hal_info * info,u32 id,u8 * buf,int length)314 static wifi_error process_bt_coex_event(hal_info *info, u32 id,
315 u8* buf, int length)
316 {
317 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
318 wifi_ring_buffer_entry *pRingBufferEntry;
319 tlv_log *pTlv;
320 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
321 u8 out_buf[RING_BUF_ENTRY_SIZE];
322 u8 link_id, link_state, link_role, link_type = 0, Rsco = 0;
323 u16 Tsco = 0;
324 wifi_error status;
325 bt_coex_hid_vendor_data_t btCoexHidVenData;
326
327 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
328 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
329 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
330 (pRingBufferEntry + 1);
331
332 switch (id) {
333 case EVENT_WLAN_BT_COEX_BT_SCO_START:
334 {
335 wlan_bt_coex_bt_sco_start_payload_type *pBtCoexStartPL;
336 pBtCoexStartPL = (wlan_bt_coex_bt_sco_start_payload_type *)buf;
337
338 link_id = pBtCoexStartPL->link_id;
339 link_state = pBtCoexStartPL->link_state;
340 link_role = pBtCoexStartPL->link_role;
341 link_type = pBtCoexStartPL->link_type;
342 Tsco = pBtCoexStartPL->Tsco;
343 Rsco = pBtCoexStartPL->Rsco;
344
345 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCO_START;
346 }
347 break;
348 case EVENT_WLAN_BT_COEX_BT_SCO_STOP:
349 {
350 wlan_bt_coex_bt_sco_stop_payload_type *pBtCoexStopPL;
351 pBtCoexStopPL = (wlan_bt_coex_bt_sco_stop_payload_type *)buf;
352
353 link_id = pBtCoexStopPL->link_id;
354 link_state = pBtCoexStopPL->link_state;
355 link_role = pBtCoexStopPL->link_role;
356 link_type = pBtCoexStopPL->link_type;
357 Tsco = pBtCoexStopPL->Tsco;
358 Rsco = pBtCoexStopPL->Rsco;
359
360 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCO_STOP;
361 }
362 break;
363 case EVENT_WLAN_BT_COEX_BT_HID_START:
364 {
365 wlan_bt_coex_bt_hid_start_payload_type *pBtCoexHidStartPL;
366 pBtCoexHidStartPL = (wlan_bt_coex_bt_hid_start_payload_type *)buf;
367
368 link_id = pBtCoexHidStartPL->link_id;
369 link_state = pBtCoexHidStartPL->link_state;
370 link_role = pBtCoexHidStartPL->link_role;
371 btCoexHidVenData.Tsniff = pBtCoexHidStartPL->Tsniff;
372 btCoexHidVenData.attempts = pBtCoexHidStartPL->attempts;
373
374 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_HID_START;
375 }
376 break;
377 case EVENT_WLAN_BT_COEX_BT_HID_STOP:
378 {
379 wlan_bt_coex_bt_hid_stop_payload_type *pBtCoexHidStopPL;
380 pBtCoexHidStopPL = (wlan_bt_coex_bt_hid_stop_payload_type *)buf;
381
382 link_id = pBtCoexHidStopPL->link_id;
383 link_state = pBtCoexHidStopPL->link_state;
384 link_role = pBtCoexHidStopPL->link_role;
385 btCoexHidVenData.Tsniff = pBtCoexHidStopPL->Tsniff;
386 btCoexHidVenData.attempts = pBtCoexHidStopPL->attempts;
387
388 pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_HID_STOP;
389 }
390 break;
391 default:
392 return WIFI_SUCCESS;
393 }
394
395 pTlv = &pConnectEvent->tlvs[0];
396 pTlv = addLoggerTlv(WIFI_TAG_LINK_ID, sizeof(link_id), &link_id, pTlv);
397 tot_len += sizeof(tlv_log) + sizeof(link_id);
398
399 pTlv = addLoggerTlv(WIFI_TAG_LINK_ROLE, sizeof(link_role),
400 &link_role, pTlv);
401 tot_len += sizeof(tlv_log) + sizeof(link_role);
402
403 pTlv = addLoggerTlv(WIFI_TAG_LINK_STATE, sizeof(link_state),
404 &link_state, pTlv);
405 tot_len += sizeof(tlv_log) + sizeof(link_state);
406
407 if ((pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_SCO_START) ||
408 (pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_SCO_STOP)) {
409 pTlv = addLoggerTlv(WIFI_TAG_LINK_TYPE, sizeof(link_type),
410 &link_type, pTlv);
411 tot_len += sizeof(tlv_log) + sizeof(link_type);
412
413 pTlv = addLoggerTlv(WIFI_TAG_TSCO, sizeof(Tsco), (u8 *)&Tsco, pTlv);
414 tot_len += sizeof(tlv_log) + sizeof(Tsco);
415
416 pTlv = addLoggerTlv(WIFI_TAG_RSCO, sizeof(Rsco), &Rsco, pTlv);
417 tot_len += sizeof(tlv_log) + sizeof(Rsco);
418 } else if ((pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_HID_START) ||
419 (pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_HID_STOP)) {
420 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
421 sizeof(bt_coex_hid_vendor_data_t),
422 (u8 *)&btCoexHidVenData, pTlv);
423 tot_len += sizeof(tlv_log) + sizeof(bt_coex_hid_vendor_data_t);
424 }
425
426 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
427 if (status != WIFI_SUCCESS) {
428 ALOGE("Failed to write bt_coex_event into ring buffer");
429 }
430
431 return status;
432 }
433
process_extscan_event(hal_info * info,u32 id,u8 * buf,int length)434 static wifi_error process_extscan_event(hal_info *info, u32 id,
435 u8* buf, int length)
436 {
437 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
438 wifi_ring_buffer_entry *pRingBufferEntry;
439 tlv_log *pTlv;
440 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
441 u8 out_buf[RING_BUF_ENTRY_SIZE];
442 wifi_error status;
443
444 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
445 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
446 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
447 (pRingBufferEntry + 1);
448 pTlv = &pConnectEvent->tlvs[0];
449
450 switch (id) {
451 case EVENT_WLAN_EXTSCAN_CYCLE_STARTED:
452 {
453 ext_scan_cycle_vendor_data_t extScanCycleVenData;
454 wlan_ext_scan_cycle_started_payload_type *pExtScanCycleStarted;
455 pConnectEvent->event = WIFI_EVENT_G_SCAN_CYCLE_STARTED;
456 pExtScanCycleStarted =
457 (wlan_ext_scan_cycle_started_payload_type *)buf;
458 pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID, sizeof(u32),
459 (u8 *)&pExtScanCycleStarted->scan_id, pTlv);
460 tot_len += sizeof(tlv_log) + sizeof(u32);
461
462 extScanCycleVenData.timer_tick = pExtScanCycleStarted->timer_tick;
463 extScanCycleVenData.scheduled_bucket_mask =
464 pExtScanCycleStarted->scheduled_bucket_mask;
465 extScanCycleVenData.scan_cycle_count =
466 pExtScanCycleStarted->scan_cycle_count;
467
468 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
469 sizeof(ext_scan_cycle_vendor_data_t),
470 (u8 *)&extScanCycleVenData, pTlv);
471 tot_len += sizeof(tlv_log) + sizeof(ext_scan_cycle_vendor_data_t);
472 }
473 break;
474 case EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED:
475 {
476 ext_scan_cycle_vendor_data_t extScanCycleVenData;
477 wlan_ext_scan_cycle_completed_payload_type *pExtScanCycleCompleted;
478 pConnectEvent->event = WIFI_EVENT_G_SCAN_CYCLE_COMPLETED;
479 pExtScanCycleCompleted =
480 (wlan_ext_scan_cycle_completed_payload_type *)buf;
481 pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID, sizeof(u32),
482 (u8 *)&pExtScanCycleCompleted->scan_id, pTlv);
483 tot_len += sizeof(tlv_log) + sizeof(u32);
484
485 extScanCycleVenData.timer_tick = pExtScanCycleCompleted->timer_tick;
486 extScanCycleVenData.scheduled_bucket_mask =
487 pExtScanCycleCompleted->scheduled_bucket_mask;
488 extScanCycleVenData.scan_cycle_count =
489 pExtScanCycleCompleted->scan_cycle_count;
490
491 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
492 sizeof(ext_scan_cycle_vendor_data_t),
493 (u8 *)&extScanCycleVenData, pTlv);
494 tot_len += sizeof(tlv_log) + sizeof(ext_scan_cycle_vendor_data_t);
495 }
496 break;
497 case EVENT_WLAN_EXTSCAN_BUCKET_STARTED:
498 {
499 wlan_ext_scan_bucket_started_payload_type *pExtScanBucketStarted;
500 u32 bucket_id;
501 pConnectEvent->event = WIFI_EVENT_G_SCAN_BUCKET_STARTED;
502 pExtScanBucketStarted =
503 (wlan_ext_scan_bucket_started_payload_type *)buf;
504 bucket_id = (u32)pExtScanBucketStarted->bucket_id;
505 pTlv = addLoggerTlv(WIFI_TAG_BUCKET_ID, sizeof(u32),
506 (u8 *)&bucket_id, pTlv);
507 tot_len += sizeof(tlv_log) + sizeof(u32);
508 }
509 break;
510 case EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED:
511 {
512 wlan_ext_scan_bucket_completed_payload_type *pExtScanBucketCmpleted;
513 u32 bucket_id;
514 pConnectEvent->event = WIFI_EVENT_G_SCAN_BUCKET_COMPLETED;
515 pExtScanBucketCmpleted =
516 (wlan_ext_scan_bucket_completed_payload_type *)buf;
517 bucket_id = (u32)pExtScanBucketCmpleted->bucket_id;
518 pTlv = addLoggerTlv(WIFI_TAG_BUCKET_ID, sizeof(u32),
519 (u8 *)&bucket_id, pTlv);
520 tot_len += sizeof(tlv_log) + sizeof(u32);
521 }
522 break;
523 case EVENT_WLAN_EXTSCAN_FEATURE_STOP:
524 {
525 wlan_ext_scan_feature_stop_payload_type *pExtScanStop;
526 pConnectEvent->event = WIFI_EVENT_G_SCAN_STOP;
527 pExtScanStop = (wlan_ext_scan_feature_stop_payload_type *)buf;
528 pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID,
529 sizeof(pExtScanStop->request_id),
530 (u8 *)&pExtScanStop->request_id, pTlv);
531 tot_len += sizeof(tlv_log) +
532 sizeof(wlan_ext_scan_feature_stop_payload_type);
533 }
534 break;
535 case EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE:
536 {
537 wlan_ext_scan_results_available_payload_type *pExtScanResultsAvail;
538 ext_scan_results_available_vendor_data_t extScanResultsAvailVenData;
539 u32 request_id;
540 pConnectEvent->event = WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE;
541 pExtScanResultsAvail =
542 (wlan_ext_scan_results_available_payload_type *)buf;
543 request_id = pExtScanResultsAvail->request_id;
544 pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID, sizeof(u32),
545 (u8 *)&request_id, pTlv);
546 tot_len += sizeof(tlv_log) + sizeof(u32);
547
548 extScanResultsAvailVenData.table_type =
549 pExtScanResultsAvail->table_type;
550 extScanResultsAvailVenData.entries_in_use =
551 pExtScanResultsAvail->entries_in_use;
552 extScanResultsAvailVenData.maximum_entries =
553 pExtScanResultsAvail->maximum_entries;
554 extScanResultsAvailVenData.scan_count_after_getResults =
555 pExtScanResultsAvail->scan_count_after_getResults;
556 extScanResultsAvailVenData.threshold_num_scans =
557 pExtScanResultsAvail->threshold_num_scans;
558
559 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
560 sizeof(ext_scan_results_available_vendor_data_t),
561 (u8 *)&extScanResultsAvailVenData, pTlv);
562 tot_len += sizeof(tlv_log) +
563 sizeof(ext_scan_results_available_vendor_data_t);
564 }
565 break;
566 }
567
568 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
569 if (status != WIFI_SUCCESS) {
570 ALOGE("Failed to write ext_scan event into ring buffer");
571 }
572
573 return status;
574 }
575
process_addba_success_event(hal_info * info,u8 * buf,int length)576 static wifi_error process_addba_success_event(hal_info *info,
577 u8* buf, int length)
578 {
579 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
580 wifi_ring_buffer_entry *pRingBufferEntry;
581 tlv_log *pTlv;
582 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
583 u8 out_buf[RING_BUF_ENTRY_SIZE];
584 wlan_add_block_ack_success_payload_type *pAddBASuccess;
585 addba_success_vendor_data_t addBASuccessVenData;
586 wifi_error status;
587
588 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
589 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
590 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
591 (pRingBufferEntry + 1);
592 pAddBASuccess = (wlan_add_block_ack_success_payload_type *)buf;
593
594 addBASuccessVenData.ucBaTid = pAddBASuccess->ucBaTid;
595 addBASuccessVenData.ucBaBufferSize = pAddBASuccess->ucBaBufferSize;
596 addBASuccessVenData.ucBaSSN = pAddBASuccess->ucBaSSN;
597 addBASuccessVenData.fInitiator = pAddBASuccess->fInitiator;
598
599 pConnectEvent->event = WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE;
600 pTlv = &pConnectEvent->tlvs[0];
601 pTlv = addLoggerTlv(WIFI_TAG_ADDR, sizeof(pAddBASuccess->ucBaPeerMac),
602 (u8 *)pAddBASuccess->ucBaPeerMac, pTlv);
603 tot_len += sizeof(tlv_log) + sizeof(pAddBASuccess->ucBaPeerMac);
604
605 tot_len += add_status_tag(&pTlv, (int)ADDBA_SUCCESS);
606
607 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
608 sizeof(addba_success_vendor_data_t),
609 (u8 *)&addBASuccessVenData, pTlv);
610 tot_len += sizeof(tlv_log) + sizeof(addba_success_vendor_data_t);
611
612 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
613 if (status != WIFI_SUCCESS) {
614 ALOGE("Failed to write addba event into ring buffer");
615 }
616
617 return status;
618 }
619
process_addba_failed_event(hal_info * info,u8 * buf,int length)620 static wifi_error process_addba_failed_event(hal_info *info,
621 u8* buf, int length)
622 {
623 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
624 wifi_ring_buffer_entry *pRingBufferEntry;
625 tlv_log *pTlv;
626 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
627 u8 out_buf[RING_BUF_ENTRY_SIZE];
628 wlan_add_block_ack_failed_payload_type *pAddBAFailed;
629 addba_failed_vendor_data_t addBAFailedVenData;
630 wifi_error status;
631
632 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
633 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
634 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
635 (pRingBufferEntry + 1);
636
637 pAddBAFailed = (wlan_add_block_ack_failed_payload_type *)buf;
638 addBAFailedVenData.ucBaTid = pAddBAFailed->ucBaTid;
639 addBAFailedVenData.fInitiator = pAddBAFailed->fInitiator;
640
641 pConnectEvent->event = WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE;
642 pTlv = &pConnectEvent->tlvs[0];
643 pTlv = addLoggerTlv(WIFI_TAG_ADDR, sizeof(pAddBAFailed->ucBaPeerMac),
644 (u8 *)pAddBAFailed->ucBaPeerMac, pTlv);
645 tot_len += sizeof(tlv_log) + sizeof(pAddBAFailed->ucBaPeerMac);
646
647 tot_len += add_status_tag(&pTlv, (int)ADDBA_FAILURE);
648
649 tot_len += add_reason_code_tag(&pTlv, (u16)pAddBAFailed->ucReasonCode);
650
651 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
652 sizeof(addba_failed_vendor_data_t),
653 (u8 *)&addBAFailedVenData, pTlv);
654 tot_len += sizeof(tlv_log) + sizeof(addba_failed_vendor_data_t);
655
656 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
657 if (status != WIFI_SUCCESS) {
658 ALOGE("Failed to write addba event into ring buffer");
659 }
660
661 return status;
662 }
663
process_roam_event(hal_info * info,u32 id,u8 * buf,int length)664 static wifi_error process_roam_event(hal_info *info, u32 id,
665 u8* buf, int length)
666 {
667 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
668 wifi_ring_buffer_entry *pRingBufferEntry;
669 tlv_log *pTlv;
670 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
671 u8 out_buf[RING_BUF_ENTRY_SIZE];
672 wifi_error status;
673
674 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
675 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
676 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
677 (pRingBufferEntry + 1);
678
679 switch (id)
680 {
681 case EVENT_WLAN_ROAM_SCAN_STARTED:
682 {
683 wlan_roam_scan_started_payload_type *pRoamScanStarted;
684 roam_scan_started_vendor_data_t roamScanStartedVenData;
685 pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_STARTED;
686 pRoamScanStarted = (wlan_roam_scan_started_payload_type *)buf;
687 pTlv = &pConnectEvent->tlvs[0];
688 pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID,
689 sizeof(pRoamScanStarted->scan_id),
690 (u8 *)&pRoamScanStarted->scan_id, pTlv);
691 tot_len += sizeof(tlv_log) + sizeof(pRoamScanStarted->scan_id);
692 roamScanStartedVenData.roam_scan_flags =
693 pRoamScanStarted->roam_scan_flags;
694 roamScanStartedVenData.cur_rssi = pRoamScanStarted->cur_rssi;
695 memcpy(roamScanStartedVenData.scan_params,
696 pRoamScanStarted->scan_params,
697 sizeof(roamScanStartedVenData.scan_params));
698 memcpy(roamScanStartedVenData.scan_channels,
699 pRoamScanStarted->scan_channels,
700 sizeof(roamScanStartedVenData.scan_channels));
701 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
702 sizeof(roam_scan_started_vendor_data_t),
703 (u8 *)&roamScanStartedVenData, pTlv);
704 tot_len += sizeof(tlv_log) +
705 sizeof(roam_scan_started_vendor_data_t);
706 }
707 break;
708 case EVENT_WLAN_ROAM_SCAN_COMPLETE:
709 {
710 wlan_roam_scan_complete_payload_type *pRoamScanComplete;
711 roam_scan_complete_vendor_data_t roamScanCompleteVenData;
712 pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_COMPLETE;
713 pRoamScanComplete = (wlan_roam_scan_complete_payload_type *)buf;
714 pTlv = &pConnectEvent->tlvs[0];
715
716 pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID,
717 sizeof(pRoamScanComplete->scan_id),
718 (u8 *)&pRoamScanComplete->scan_id, pTlv);
719 tot_len += sizeof(tlv_log) + sizeof(pRoamScanComplete->scan_id);
720
721 roamScanCompleteVenData.reason = pRoamScanComplete->reason;
722 roamScanCompleteVenData.completion_flags =
723 pRoamScanComplete->completion_flags;
724 roamScanCompleteVenData.num_candidate =
725 pRoamScanComplete->num_candidate;
726 roamScanCompleteVenData.flags = pRoamScanComplete->flags;
727
728 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
729 sizeof(roam_scan_complete_vendor_data_t),
730 (u8 *)&roamScanCompleteVenData, pTlv);
731 tot_len += sizeof(tlv_log) +
732 sizeof(roam_scan_complete_vendor_data_t);
733 }
734 break;
735 case EVENT_WLAN_ROAM_CANDIDATE_FOUND:
736 {
737 wlan_roam_candidate_found_payload_type *pRoamCandidateFound;
738 roam_candidate_found_vendor_data_t roamCandidateFoundVendata;
739 pConnectEvent->event = WIFI_EVENT_ROAM_CANDIDATE_FOUND;
740 pRoamCandidateFound = (wlan_roam_candidate_found_payload_type *)buf;
741 memset(&roamCandidateFoundVendata, 0,
742 sizeof(roam_candidate_found_vendor_data_t));
743 pTlv = &pConnectEvent->tlvs[0];
744 pTlv = addLoggerTlv(WIFI_TAG_CHANNEL,
745 sizeof(pRoamCandidateFound->channel),
746 (u8 *)&pRoamCandidateFound->channel, pTlv);
747 tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->channel);
748
749 pTlv = addLoggerTlv(WIFI_TAG_RSSI,
750 sizeof(pRoamCandidateFound->rssi),
751 (u8 *)&pRoamCandidateFound->rssi, pTlv);
752 tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->rssi);
753
754 pTlv = addLoggerTlv(WIFI_TAG_BSSID,
755 sizeof(pRoamCandidateFound->bssid),
756 (u8 *)pRoamCandidateFound->bssid, pTlv);
757 tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->bssid);
758
759 pTlv = addLoggerTlv(WIFI_TAG_SSID,
760 sizeof(pRoamCandidateFound->ssid),
761 (u8 *)pRoamCandidateFound->ssid, pTlv);
762 tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->ssid);
763
764 roamCandidateFoundVendata.auth_mode =
765 pRoamCandidateFound->auth_mode;
766 roamCandidateFoundVendata.ucast_cipher =
767 pRoamCandidateFound->ucast_cipher;
768 roamCandidateFoundVendata.mcast_cipher =
769 pRoamCandidateFound->mcast_cipher;
770 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
771 sizeof(roam_candidate_found_vendor_data_t),
772 (u8 *)&roamCandidateFoundVendata, pTlv);
773 tot_len += sizeof(tlv_log) +
774 sizeof(roam_candidate_found_vendor_data_t);
775 }
776 break;
777 case EVENT_WLAN_ROAM_SCAN_CONFIG:
778 {
779 wlan_roam_scan_config_payload_type *pRoamScanConfig;
780 roam_scan_config_vendor_data_t roamScanConfigVenData;
781
782 pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_CONFIG;
783 pRoamScanConfig = (wlan_roam_scan_config_payload_type *)buf;
784
785 pTlv = &pConnectEvent->tlvs[0];
786
787 roamScanConfigVenData.flags = pRoamScanConfig->flags;
788 memcpy(roamScanConfigVenData.roam_scan_config,
789 pRoamScanConfig->roam_scan_config,
790 sizeof(roamScanConfigVenData.roam_scan_config));
791
792 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
793 sizeof(roam_scan_config_vendor_data_t),
794 (u8 *)&roamScanConfigVenData, pTlv);
795 tot_len += sizeof(tlv_log) +
796 sizeof(roam_scan_config_vendor_data_t);
797 }
798 break;
799 }
800
801 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
802 if (status != WIFI_SUCCESS) {
803 ALOGE("Failed to write roam event into ring buffer");
804 }
805
806 return status;
807 }
808
process_firmware_prints(hal_info * info,u8 * buf,u16 length)809 wifi_error process_firmware_prints(hal_info *info, u8 *buf, u16 length)
810 {
811 wifi_ring_buffer_entry rb_entry_hdr;
812 struct timeval time;
813 wifi_error status;
814
815 rb_entry_hdr.entry_size = length;
816 rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
817 rb_entry_hdr.type = ENTRY_TYPE_DATA;
818 gettimeofday(&time, NULL);
819 rb_entry_hdr.timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
820
821 /* Write if verbose and handler is set */
822 if (info->rb_infos[FIRMWARE_PRINTS_RB_ID].verbose_level >= 1 &&
823 info->on_ring_buffer_data) {
824 /* Write header and payload separately to avoid
825 * complete payload memcpy */
826 status = ring_buffer_write(&info->rb_infos[FIRMWARE_PRINTS_RB_ID],
827 (u8*)&rb_entry_hdr,
828 sizeof(wifi_ring_buffer_entry),
829 0,
830 sizeof(wifi_ring_buffer_entry) + length);
831 if (status != WIFI_SUCCESS) {
832 ALOGE("Failed to write firmware prints rb header %d", status);
833 return status;
834 }
835 status = ring_buffer_write(&info->rb_infos[FIRMWARE_PRINTS_RB_ID],
836 buf, length, 1, length);
837 if (status != WIFI_SUCCESS) {
838 ALOGE("Failed to write firmware prints rb payload %d", status);
839 return status;
840 }
841 }
842
843 return WIFI_SUCCESS;
844 }
845
process_beacon_received_event(hal_info * info,u8 * buf,int length)846 static wifi_error process_beacon_received_event(hal_info *info,
847 u8* buf, int length)
848 {
849 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
850 wifi_ring_buffer_entry *pRingBufferEntry;
851 tlv_log *pTlv;
852 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
853 u8 out_buf[RING_BUF_ENTRY_SIZE];
854 wlan_beacon_received_payload_type *pBeaconRcvd;
855 u32 rssi;
856 wifi_error status;
857
858 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
859 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
860 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
861 (pRingBufferEntry + 1);
862
863 pBeaconRcvd = (wlan_beacon_received_payload_type *)buf;
864
865 pConnectEvent->event = WIFI_EVENT_BEACON_RECEIVED;
866 pTlv = &pConnectEvent->tlvs[0];
867
868 pTlv = addLoggerTlv(WIFI_TAG_BSSID, sizeof(pBeaconRcvd->bssid),
869 (u8 *)pBeaconRcvd->bssid, pTlv);
870 tot_len += sizeof(tlv_log) + sizeof(pBeaconRcvd->bssid);
871
872 rssi = get_rssi(pBeaconRcvd->beacon_rssi);
873 pTlv = addLoggerTlv(WIFI_TAG_RSSI,
874 sizeof(rssi), (u8 *)&rssi, pTlv);
875 tot_len += sizeof(tlv_log) + sizeof(pBeaconRcvd->beacon_rssi);
876
877 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
878 if (status != WIFI_SUCCESS) {
879 ALOGE("Failed to write addba event into ring buffer");
880 }
881
882 return status;
883 }
884
process_fw_diag_msg(hal_info * info,u8 * buf,u16 length)885 static wifi_error process_fw_diag_msg(hal_info *info, u8* buf, u16 length)
886 {
887 u16 count = 0, id;
888 u16 payloadlen = 0;
889 u16 hdr_size = 0;
890 wifi_error status;
891 fw_diag_msg_fixed_hdr_t *diag_msg_fixed_hdr;
892 fw_diag_msg_hdr_t *diag_msg_hdr;
893 fw_diag_msg_hdr_v2_t *diag_msg_hdr_v2;
894 u8 *payload = NULL;
895
896 buf += 4;
897 length -= 4;
898
899 while ((info && !info->clean_up)
900 && (length > (count + sizeof(fw_diag_msg_fixed_hdr_t)))) {
901 diag_msg_fixed_hdr = (fw_diag_msg_fixed_hdr_t *)(buf + count);
902
903 if (diag_msg_fixed_hdr->diag_event_type > WLAN_DIAG_TYPE_LEGACY_MSG) {
904 hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
905 } else {
906 hdr_size = sizeof(fw_diag_msg_hdr_t);
907 }
908
909 if ((count + hdr_size) > length)
910 {
911 ALOGE("process_fw_diag_msg (%d) - possible buffer over access, length=%d count=%d hdr_size=%d",
912 diag_msg_fixed_hdr->diag_event_type, length, count, hdr_size);
913 return WIFI_ERROR_UNKNOWN;
914 }
915
916 switch (diag_msg_fixed_hdr->diag_event_type) {
917 case WLAN_DIAG_TYPE_EVENT:
918 case WLAN_DIAG_TYPE_EVENT_V2:
919 {
920 if (WLAN_DIAG_TYPE_EVENT ==
921 diag_msg_fixed_hdr->diag_event_type) {
922 diag_msg_hdr = (fw_diag_msg_hdr_t *)diag_msg_fixed_hdr;
923 id = diag_msg_hdr->diag_id;
924 payloadlen = diag_msg_hdr->u.payload_len;
925 hdr_size = sizeof(fw_diag_msg_hdr_t);
926 payload = diag_msg_hdr->payload;
927 } else {
928 diag_msg_hdr_v2 =
929 (fw_diag_msg_hdr_v2_t *)diag_msg_fixed_hdr;
930 id = diag_msg_hdr_v2->diag_id;
931 payloadlen = diag_msg_hdr_v2->u.payload_len;
932 hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
933 payload = diag_msg_hdr_v2->payload;
934 }
935 if ((count + hdr_size + payloadlen) > length) {
936 ALOGE("WLAN_DIAG_TYPE_EVENT - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
937 length, count, hdr_size, payloadlen);
938 return WIFI_ERROR_UNKNOWN;
939 }
940
941 switch (id) {
942 case EVENT_WLAN_BT_COEX_BT_SCO_START:
943 case EVENT_WLAN_BT_COEX_BT_SCO_STOP:
944 case EVENT_WLAN_BT_COEX_BT_HID_START:
945 case EVENT_WLAN_BT_COEX_BT_HID_STOP:
946 status = process_bt_coex_event(info, id,
947 payload,
948 payloadlen);
949 if (status != WIFI_SUCCESS) {
950 ALOGE("Failed to process bt_coex event");
951 return status;
952 }
953 break;
954 case EVENT_WLAN_BT_COEX_BT_SCAN_START:
955 case EVENT_WLAN_BT_COEX_BT_SCAN_STOP:
956 status = process_bt_coex_scan_event(info, id,
957 payload,
958 payloadlen);
959 if (status != WIFI_SUCCESS) {
960 ALOGE("Failed to process bt_coex_scan event");
961 return status;
962 }
963 break;
964 case EVENT_WLAN_EXTSCAN_CYCLE_STARTED:
965 case EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED:
966 case EVENT_WLAN_EXTSCAN_BUCKET_STARTED:
967 case EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED:
968 case EVENT_WLAN_EXTSCAN_FEATURE_STOP:
969 case EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE:
970 status = process_extscan_event(info, id,
971 payload,
972 payloadlen);
973 if (status != WIFI_SUCCESS) {
974 ALOGE("Failed to process extscan event");
975 return status;
976 }
977 break;
978 case EVENT_WLAN_ROAM_SCAN_STARTED:
979 case EVENT_WLAN_ROAM_SCAN_COMPLETE:
980 case EVENT_WLAN_ROAM_CANDIDATE_FOUND:
981 case EVENT_WLAN_ROAM_SCAN_CONFIG:
982 status = process_roam_event(info, id,
983 payload,
984 payloadlen);
985 if (status != WIFI_SUCCESS) {
986 ALOGE("Failed to process roam event");
987 return status;
988 }
989 break;
990 case EVENT_WLAN_ADD_BLOCK_ACK_SUCCESS:
991 status = process_addba_success_event(info,
992 payload,
993 payloadlen);
994 if (status != WIFI_SUCCESS) {
995 ALOGE("Failed to process addba success event");
996 return status;
997 }
998 break;
999 case EVENT_WLAN_ADD_BLOCK_ACK_FAILED:
1000 status = process_addba_failed_event(info,
1001 payload,
1002 payloadlen);
1003 if (status != WIFI_SUCCESS) {
1004 ALOGE("Failed to process addba failed event");
1005 return status;
1006 }
1007 break;
1008 case EVENT_WLAN_BEACON_EVENT:
1009 status = process_beacon_received_event(info,
1010 payload,
1011 payloadlen);
1012 if (status != WIFI_SUCCESS) {
1013 ALOGE("Failed to process beacon received event");
1014 return status;
1015 }
1016 break;
1017 default:
1018 return WIFI_SUCCESS;
1019 }
1020 }
1021 break;
1022 case WLAN_DIAG_TYPE_LOG:
1023 case WLAN_DIAG_TYPE_LOG_V2:
1024 {
1025 if (WLAN_DIAG_TYPE_LOG == diag_msg_fixed_hdr->diag_event_type) {
1026 diag_msg_hdr = (fw_diag_msg_hdr_t *)diag_msg_fixed_hdr;
1027 id = diag_msg_hdr->diag_id;
1028 payloadlen = diag_msg_hdr->u.payload_len;
1029 hdr_size = sizeof(fw_diag_msg_hdr_t);
1030 payload = diag_msg_hdr->payload;
1031 } else {
1032 diag_msg_hdr_v2 = (fw_diag_msg_hdr_v2_t *)diag_msg_fixed_hdr;
1033 id = diag_msg_hdr_v2->diag_id;
1034 payloadlen = diag_msg_hdr_v2->u.payload_len;
1035 hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
1036 payload = diag_msg_hdr_v2->payload;
1037 }
1038 if ((count + hdr_size + payloadlen) > length) {
1039 ALOGE("WLAN_DIAG_TYPE_LOG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
1040 length, count, hdr_size, payloadlen);
1041 return WIFI_ERROR_UNKNOWN;
1042 }
1043
1044 switch (id) {
1045 case LOG_WLAN_EXTSCAN_CAPABILITIES:
1046 status = process_log_extscan_capabilities(info,
1047 payload,
1048 payloadlen);
1049 if (status != WIFI_SUCCESS) {
1050 ALOGE("Failed to process extscan capabilities");
1051 return status;
1052 }
1053 break;
1054 default:
1055 break;
1056 }
1057 }
1058 break;
1059 case WLAN_DIAG_TYPE_MSG:
1060 diag_msg_hdr = (fw_diag_msg_hdr_t *)diag_msg_fixed_hdr;
1061 id = diag_msg_hdr->diag_id;
1062 /* Length field is only one byte for WLAN_DIAG_TYPE_MSG */
1063 payloadlen = diag_msg_hdr->u.msg_hdr.payload_len;
1064 hdr_size = sizeof(fw_diag_msg_hdr_t);
1065 payload = diag_msg_hdr->payload;
1066 if ((count + hdr_size + payloadlen) > length) {
1067 ALOGE("WLAN_DIAG_TYPE_MSG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
1068 length, count, hdr_size, payloadlen);
1069 return WIFI_ERROR_UNKNOWN;
1070 }
1071 process_firmware_prints(info, (u8 *)diag_msg_fixed_hdr,
1072 payloadlen + hdr_size);
1073 break;
1074 case WLAN_DIAG_TYPE_MSG_V2:
1075 diag_msg_hdr_v2 = (fw_diag_msg_hdr_v2_t *)diag_msg_fixed_hdr;
1076 id = diag_msg_hdr_v2->diag_id;
1077 /* Length field is only one byte for WLAN_DIAG_TYPE_MSG_V2 */
1078 payloadlen = diag_msg_hdr_v2->u.msg_hdr.payload_len;
1079 hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
1080 payload = diag_msg_hdr_v2->payload;
1081 if ((count + hdr_size + payloadlen) > length) {
1082 ALOGE("WLAN_DIAG_TYPE_MSG_V2 - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
1083 length, count, hdr_size, payloadlen);
1084 return WIFI_ERROR_UNKNOWN;
1085 }
1086 process_firmware_prints(info, (u8 *)diag_msg_fixed_hdr,
1087 payloadlen + hdr_size);
1088 break;
1089 case WLAN_DIAG_TYPE_CONFIG:
1090 {
1091 /* Base timestamp is part of this diag type */
1092 diag_msg_hdr = (fw_diag_msg_hdr_t *) diag_msg_fixed_hdr;
1093 id = diag_msg_hdr->diag_id;
1094 payload = diag_msg_hdr->payload;
1095 payloadlen = diag_msg_hdr->u.payload_len;
1096 hdr_size = sizeof(fw_diag_msg_hdr_t);
1097 if ((count + hdr_size + payloadlen) > length) {
1098 ALOGE("WLAN_DIAG_TYPE_CONFIG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
1099 length, count, hdr_size, payloadlen);
1100 return WIFI_ERROR_UNKNOWN;
1101 }
1102 process_firmware_prints(info, (u8 *)diag_msg_hdr,
1103 payloadlen + hdr_size);
1104 }
1105 break;
1106 default:
1107 return WIFI_SUCCESS;
1108 }
1109 count += payloadlen + hdr_size;
1110 }
1111 return WIFI_SUCCESS;
1112 }
1113
remap_event(int in_event,int * out_event)1114 static wifi_error remap_event(int in_event, int *out_event)
1115 {
1116 int i = 0;
1117 while (i < MAX_CONNECTIVITY_EVENTS) {
1118 if (events[i].q_event == in_event) {
1119 *out_event = events[i].g_event;
1120 return WIFI_SUCCESS;
1121 }
1122 i++;
1123 }
1124 return WIFI_ERROR_UNKNOWN;
1125 }
1126
process_wlan_pe_event(hal_info * info,u8 * buf,int length)1127 static wifi_error process_wlan_pe_event(hal_info *info, u8* buf, int length)
1128 {
1129 wlan_pe_event_t *pWlanPeEvent;
1130 pe_event_vendor_data_t peEventVenData;
1131 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
1132 wifi_ring_buffer_entry *pRingBufferEntry;
1133 tlv_log *pTlv;
1134 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
1135 u8 out_buf[RING_BUF_ENTRY_SIZE];
1136 wifi_error status;
1137
1138 pWlanPeEvent = (wlan_pe_event_t *)buf;
1139
1140 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
1141 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
1142 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
1143 (pRingBufferEntry + 1);
1144
1145 status = remap_event(pWlanPeEvent->event_type,
1146 (int *)&pConnectEvent->event);
1147 if (status != WIFI_SUCCESS)
1148 return status;
1149
1150 pTlv = &pConnectEvent->tlvs[0];
1151 pTlv = addLoggerTlv(WIFI_TAG_BSSID, sizeof(pWlanPeEvent->bssid),
1152 (u8 *)pWlanPeEvent->bssid, pTlv);
1153 tot_len += sizeof(tlv_log) + sizeof(pWlanPeEvent->bssid);
1154
1155 tot_len += add_status_tag(&pTlv, (int)pWlanPeEvent->status);
1156
1157 pTlv = addLoggerTlv(WIFI_TAG_REASON_CODE, sizeof(pWlanPeEvent->reason_code),
1158 (u8 *)&pWlanPeEvent->reason_code, pTlv);
1159 tot_len += sizeof(tlv_log) + sizeof(pWlanPeEvent->reason_code);
1160
1161 peEventVenData.sme_state = pWlanPeEvent->sme_state;
1162 peEventVenData.mlm_state = pWlanPeEvent->mlm_state;
1163
1164 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
1165 sizeof(pe_event_vendor_data_t),
1166 (u8 *)&peEventVenData, pTlv);
1167 tot_len += sizeof(tlv_log) + sizeof(pe_event_vendor_data_t);
1168
1169 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
1170 if (status != WIFI_SUCCESS) {
1171 ALOGE("Failed to write pe event into ring buffer");
1172 }
1173
1174 return status;
1175 }
1176
process_wlan_eapol_event(hal_info * info,u8 * buf,int length)1177 static wifi_error process_wlan_eapol_event(hal_info *info, u8* buf, int length)
1178 {
1179 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
1180 wlan_eapol_event_t *pWlanEapolEvent;
1181 wifi_ring_buffer_entry *pRingBufferEntry;
1182 u8 out_buf[RING_BUF_ENTRY_SIZE];
1183 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
1184 tlv_log *pTlv;
1185 u32 eapol_msg_type = 0;
1186 wifi_error status;
1187
1188 pWlanEapolEvent = (wlan_eapol_event_t *)buf;
1189 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
1190 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
1191 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
1192 (pRingBufferEntry + 1);
1193
1194 if (pWlanEapolEvent->event_sub_type ==
1195 WLAN_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED)
1196 pConnectEvent->event = WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED;
1197 else
1198 pConnectEvent->event = WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED;
1199
1200 pTlv = &pConnectEvent->tlvs[0];
1201
1202 if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M1_MASK)
1203 eapol_msg_type = 1;
1204 else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M2_MASK)
1205 eapol_msg_type = 2;
1206 else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M3_MASK)
1207 eapol_msg_type = 3;
1208 else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M4_MASK)
1209 eapol_msg_type = 4;
1210 else
1211 ALOGI("Unknown EAPOL message type \n");
1212 pTlv = addLoggerTlv(WIFI_TAG_EAPOL_MESSAGE_TYPE, sizeof(u32),
1213 (u8 *)&eapol_msg_type, pTlv);
1214 tot_len += sizeof(tlv_log) + sizeof(u32);
1215 pTlv = addLoggerTlv(WIFI_TAG_ADDR1, sizeof(pWlanEapolEvent->dest_addr),
1216 (u8 *)pWlanEapolEvent->dest_addr, pTlv);
1217 tot_len += sizeof(tlv_log) + sizeof(pWlanEapolEvent->dest_addr);
1218 pTlv = addLoggerTlv(WIFI_TAG_ADDR2, sizeof(pWlanEapolEvent->src_addr),
1219 (u8 *)pWlanEapolEvent->src_addr, pTlv);
1220 tot_len += sizeof(tlv_log) + sizeof(pWlanEapolEvent->src_addr);
1221
1222 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
1223 if (status != WIFI_SUCCESS) {
1224 ALOGE("Failed to write eapol event into ring buffer");
1225 }
1226
1227 return status;
1228 }
1229
process_wakelock_event(hal_info * info,u8 * buf,int length)1230 static wifi_error process_wakelock_event(hal_info *info, u8* buf, int length)
1231 {
1232 wlan_wake_lock_event_t *pWlanWakeLockEvent;
1233 wake_lock_event *pWakeLockEvent;
1234 wifi_power_event *pPowerEvent;
1235 tlv_log *pTlv;
1236 wifi_ring_buffer_entry *pRingBufferEntry;
1237 u16 len_ring_buffer_entry;
1238 struct timeval time;
1239 wifi_error status;
1240 u8 wl_ring_buffer[RING_BUF_ENTRY_SIZE];
1241 u16 entry_size;
1242
1243 pWlanWakeLockEvent = (wlan_wake_lock_event_t *)(buf);
1244 entry_size = sizeof(wifi_power_event) +
1245 sizeof(tlv_log) +
1246 sizeof(wake_lock_event) +
1247 pWlanWakeLockEvent->name_len + 1;
1248 len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry) + entry_size;
1249
1250 if (len_ring_buffer_entry > RING_BUF_ENTRY_SIZE) {
1251 pRingBufferEntry = (wifi_ring_buffer_entry *)malloc(
1252 len_ring_buffer_entry);
1253 if (pRingBufferEntry == NULL) {
1254 ALOGE("%s: Failed to allocate memory", __FUNCTION__);
1255 return WIFI_ERROR_OUT_OF_MEMORY;
1256 }
1257 } else {
1258 pRingBufferEntry = (wifi_ring_buffer_entry *)wl_ring_buffer;
1259 }
1260
1261 pPowerEvent = (wifi_power_event *)(pRingBufferEntry + 1);
1262 pPowerEvent->event = WIFI_TAG_WAKE_LOCK_EVENT;
1263
1264 pTlv = &pPowerEvent->tlvs[0];
1265 pTlv->tag = WIFI_TAG_WAKE_LOCK_EVENT;
1266 pTlv->length = sizeof(wake_lock_event) +
1267 pWlanWakeLockEvent->name_len + 1;
1268
1269 pWakeLockEvent = (wake_lock_event *)pTlv->value;
1270 pWakeLockEvent->status = pWlanWakeLockEvent->status;
1271 pWakeLockEvent->reason = pWlanWakeLockEvent->reason;
1272 memcpy(pWakeLockEvent->name, pWlanWakeLockEvent->name,
1273 pWlanWakeLockEvent->name_len);
1274
1275 pRingBufferEntry->entry_size = entry_size;
1276 pRingBufferEntry->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY |
1277 RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
1278 pRingBufferEntry->type = ENTRY_TYPE_POWER_EVENT;
1279 gettimeofday(&time, NULL);
1280 pRingBufferEntry->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
1281
1282 /* Write if verbose and handler is set */
1283 if (info->rb_infos[POWER_EVENTS_RB_ID].verbose_level >= 1 &&
1284 info->on_ring_buffer_data) {
1285 status = ring_buffer_write(&info->rb_infos[POWER_EVENTS_RB_ID],
1286 (u8*)pRingBufferEntry,
1287 len_ring_buffer_entry,
1288 1,
1289 len_ring_buffer_entry);
1290 } else {
1291 status = WIFI_SUCCESS;
1292 }
1293
1294 if ((u8 *)pRingBufferEntry != wl_ring_buffer) {
1295 ALOGI("Message with more than RING_BUF_ENTRY_SIZE");
1296 free(pRingBufferEntry);
1297 }
1298
1299 return status;
1300 }
1301
process_wlan_log_complete_event(hal_info * info,u8 * buf,int length)1302 static void process_wlan_log_complete_event(hal_info *info,
1303 u8* buf,
1304 int length)
1305 {
1306 wlan_log_complete_event_t *lfd_event;
1307
1308 ALOGV("Received log completion event from driver");
1309 lfd_event = (wlan_log_complete_event_t *)buf;
1310
1311 push_out_all_ring_buffers(info);
1312
1313 if (lfd_event->is_fatal == WLAN_LOG_TYPE_FATAL) {
1314 ALOGE("Received fatal event, sending alert");
1315 send_alert(info, lfd_event->reason_code);
1316 }
1317 }
1318
process_wlan_data_stall_event(hal_info * info,u8 * buf,int length)1319 static void process_wlan_data_stall_event(hal_info *info,
1320 u8* buf,
1321 int length)
1322 {
1323 wlan_data_stall_event_t *event;
1324
1325 ALOGV("Received Data Stall Event from Driver");
1326 event = (wlan_data_stall_event_t *)buf;
1327 ALOGE("Received Data Stall event, sending alert %d", event->reason);
1328 send_alert(info, DATA_STALL_OFFSET_REASON_CODE + event->reason);
1329 }
1330
process_wlan_low_resource_failure(hal_info * info,u8 * buf,u16 length)1331 static void process_wlan_low_resource_failure(hal_info *info,
1332 u8* buf,
1333 u16 length)
1334 {
1335 wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
1336 wlan_low_resource_failure_event_t *pWlanResourceEvent;
1337 resource_failure_vendor_data_t cap_vendor_data;
1338 wifi_ring_buffer_entry *pRingBufferEntry;
1339 u8 out_buf[RING_BUF_ENTRY_SIZE];
1340 int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
1341 tlv_log *pTlv;
1342 wifi_error status;
1343
1344 pWlanResourceEvent = (wlan_low_resource_failure_event_t *)buf;
1345 pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
1346 memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
1347 pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
1348 (pRingBufferEntry + 1);
1349
1350 pConnectEvent->event = WIFI_EVENT_MEM_ALLOC_FAILURE;
1351 memset(&cap_vendor_data, 0, sizeof(resource_failure_vendor_data_t));
1352
1353 if (length > sizeof(resource_failure_vendor_data_t)) {
1354 ALOGE("Received resource failure event of size : %d, whereas expected"
1355 " size is <= %zu bytes", length,
1356 sizeof(resource_failure_vendor_data_t));
1357 return;
1358 }
1359 memcpy(&cap_vendor_data, pWlanResourceEvent, length);
1360
1361 pTlv = &pConnectEvent->tlvs[0];
1362 pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
1363 sizeof(resource_failure_vendor_data_t),
1364 (u8 *)&cap_vendor_data, pTlv);
1365 tot_len += sizeof(tlv_log) + sizeof(resource_failure_vendor_data_t);
1366
1367 status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
1368 if (status != WIFI_SUCCESS) {
1369 ALOGE("Failed to write resource failure event into ring buffer");
1370 }
1371 }
1372
1373
update_stats_to_ring_buf(hal_info * info,u8 * rb_entry,u32 size)1374 static wifi_error update_stats_to_ring_buf(hal_info *info,
1375 u8 *rb_entry, u32 size)
1376 {
1377 int num_records = 1;
1378 wifi_ring_buffer_entry *pRingBufferEntry =
1379 (wifi_ring_buffer_entry *)rb_entry;
1380 struct timeval time;
1381
1382 pRingBufferEntry->entry_size = size - sizeof(wifi_ring_buffer_entry);
1383 pRingBufferEntry->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY |
1384 RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
1385 pRingBufferEntry->type = ENTRY_TYPE_PKT;
1386 gettimeofday(&time,NULL);
1387 pRingBufferEntry->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
1388
1389 // Write if verbose and handler is set
1390 if ((info->rb_infos[PKT_STATS_RB_ID].verbose_level >= VERBOSE_REPRO_PROBLEM)
1391 && info->on_ring_buffer_data) {
1392 ring_buffer_write(&info->rb_infos[PKT_STATS_RB_ID],
1393 (u8*)pRingBufferEntry,
1394 size,
1395 num_records,
1396 size);
1397 }
1398
1399 return WIFI_SUCCESS;
1400 }
1401
cck_ratecode_mapping(u8 rate)1402 static u8 cck_ratecode_mapping(u8 rate)
1403 {
1404 u8 rate_code = 0;
1405
1406 switch (rate) {
1407 case 0x1:
1408 rate_code = 0x3;
1409 break;
1410 case 0x2:
1411 case 0x5:
1412 rate_code = 0x2;
1413 break;
1414 case 0x3:
1415 case 0x6:
1416 rate_code = 0x1;
1417 break;
1418 case 0x4:
1419 case 0x7:
1420 rate_code = 0x0;
1421 break;
1422 }
1423 return rate_code;
1424 }
1425
ofdm_ratecode_mapping(u8 rate)1426 static u8 ofdm_ratecode_mapping(u8 rate)
1427 {
1428 u8 rate_code = 0;
1429
1430 rate_code = rate - 8;
1431 return rate_code;
1432 }
1433
get_rate_v1(u16 mcs_r)1434 static u16 get_rate_v1(u16 mcs_r)
1435 {
1436 MCS mcs;
1437 int index = 0;
1438 u16 tx_rate = 0;
1439 u8 nss;
1440
1441 mcs.mcs = mcs_r;
1442 nss = mcs.mcs_s.nss + 1;
1443
1444 switch (mcs.mcs_s.preamble) {
1445 case WIFI_HW_RATECODE_PREAM_OFDM:
1446 for (index = 0; index < MAX_OFDM_MCS_IDX; index++) {
1447 if ((mcs.mcs_s.rate & 0xF) == index)
1448 tx_rate = (u16) ofdm_mcs_nss1[index].ofdm_rate[mcs.mcs_s.short_gi] / 1000;
1449 }
1450 break;
1451 case WIFI_HW_RATECODE_PREAM_CCK:
1452 for (index = 0; index < MAX_CCK_MCS_IDX; index++) {
1453 if ((mcs.mcs_s.rate & 0xF) == index)
1454 tx_rate = (u16) cck_mcs_nss1[index].cck_rate[mcs.mcs_s.short_gi] / 1000;
1455 }
1456 break;
1457 case WIFI_HW_RATECODE_PREAM_HT:
1458 if (nss == 1) {
1459 for (index = 0; index < MAX_HT_MCS_IDX; index++) {
1460 if (mcs.mcs_s.rate == index) {
1461 if (mcs.mcs_s.bw == BW_20MHZ)
1462 tx_rate = (u16) mcs_nss1[index].ht20_rate[mcs.mcs_s.short_gi] / 10;
1463 if (mcs.mcs_s.bw == BW_40MHZ)
1464 tx_rate = (u16) mcs_nss1[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
1465 }
1466 }
1467 } else if (nss == 2) {
1468 for (index = 0; index < MAX_HT_MCS_IDX; index++) {
1469 if (mcs.mcs_s.rate == index) {
1470 if (mcs.mcs_s.bw == BW_20MHZ)
1471 tx_rate = (u16) mcs_nss2[index].ht20_rate[mcs.mcs_s.short_gi] / 10;
1472 if (mcs.mcs_s.bw == BW_40MHZ)
1473 tx_rate = (u16) mcs_nss2[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
1474 }
1475 }
1476 } else {
1477 ALOGE("Unexpected nss %d", nss);
1478 }
1479 break;
1480 case WIFI_HW_RATECODE_PREAM_VHT:
1481 if (nss == 1) {
1482 for (index = 0; index < MAX_VHT_MCS_IDX; index++) {
1483 if (mcs.mcs_s.rate == index) {
1484 if (mcs.mcs_s.bw == BW_20MHZ)
1485 tx_rate = (u16) vht_mcs_nss1[index].ht20_rate[mcs.mcs_s.short_gi] / 10;
1486 if (mcs.mcs_s.bw == BW_40MHZ)
1487 tx_rate = (u16) vht_mcs_nss1[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
1488 if (mcs.mcs_s.bw == BW_80MHZ)
1489 tx_rate = (u16) vht_mcs_nss1[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
1490 }
1491 }
1492 } else if (nss == 2) {
1493 for (index = 0; index < MAX_VHT_MCS_IDX; index++) {
1494 if (mcs.mcs_s.rate == index) {
1495 if (mcs.mcs_s.bw == BW_20MHZ)
1496 tx_rate = (u16) vht_mcs_nss2[index].ht20_rate[mcs.mcs_s.short_gi] / 10;
1497 if (mcs.mcs_s.bw == BW_40MHZ)
1498 tx_rate = (u16) vht_mcs_nss2[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
1499 if (mcs.mcs_s.bw == BW_80MHZ)
1500 tx_rate = (u16) vht_mcs_nss2[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
1501 }
1502 }
1503 } else {
1504 ALOGE("Unexpected nss %d", nss);
1505 }
1506 break;
1507 default:
1508 ALOGE("Unexpected preamble %d", mcs.mcs_s.preamble);
1509 }
1510 return tx_rate;
1511 }
1512
get_rate(u16 mcs_r)1513 static u16 get_rate(u16 mcs_r)
1514 {
1515 u16 tx_rate = 0;
1516 MCS mcs;
1517 static u16 rate_lookup[][8] = {{96, 48, 24, 12, 108, 72, 36, 18},
1518 {22, 11, 4, 2, 22, 11, 4, 0}};
1519 static u16 MCS_rate_lookup_ht[][8] =
1520 {{ 13, 14, 27, 30, 59, 65, 117, 130},
1521 { 26, 29, 54, 60, 117, 130, 234, 260},
1522 { 39, 43, 81, 90, 176, 195, 351, 390},
1523 { 52, 58, 108, 120, 234, 260, 468, 520},
1524 { 78, 87, 162, 180, 351, 390, 702, 780},
1525 {104, 116, 216, 240, 468, 520, 936, 1040},
1526 {117, 130, 243, 270, 527, 585, 1053, 1170},
1527 {130, 144, 270, 300, 585, 650, 1170, 1300},
1528 {156, 173, 324, 360, 702, 780, 1404, 1560},
1529 { 0, 0, 360, 400, 780, 867, 1560, 1733},
1530 { 26, 29, 54, 60, 117, 130, 234, 260},
1531 { 52, 58, 108, 120, 234, 260, 468, 520},
1532 { 78, 87, 162, 180, 351, 390, 702, 780},
1533 {104, 116, 216, 240, 468, 520, 936, 1040},
1534 {156, 173, 324, 360, 702, 780, 1404, 1560},
1535 {208, 231, 432, 480, 936,1040, 1872, 2080},
1536 {234, 261, 486, 540,1053,1170, 2106, 2340},
1537 {260, 289, 540, 600,1170,1300, 2340, 2600},
1538 {312, 347, 648, 720,1404,1560, 2808, 3120},
1539 { 0, 0, 720, 800,1560,1733, 3120, 3467}};
1540
1541 mcs.mcs = mcs_r;
1542 if ((mcs.mcs_s.preamble <= WL_PREAMBLE_VHT) && (mcs.mcs_s.rate < 10)) {
1543 switch(mcs.mcs_s.preamble)
1544 {
1545 case WL_PREAMBLE_CCK:
1546 case WL_PREAMBLE_OFDM:
1547 if(mcs.mcs_s.rate<8) {
1548 tx_rate = rate_lookup [mcs.mcs_s.preamble][mcs.mcs_s.rate];
1549 if (mcs.mcs_s.nss)
1550 tx_rate *=2;
1551 } else {
1552 ALOGE("Unexpected rate value");
1553 }
1554 break;
1555 case WL_PREAMBLE_HT:
1556 if(mcs.mcs_s.rate<8) {
1557 if (!mcs.mcs_s.nss)
1558 tx_rate = MCS_rate_lookup_ht[mcs.mcs_s.rate]
1559 [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi];
1560 else
1561 tx_rate = MCS_rate_lookup_ht[10+mcs.mcs_s.rate]
1562 [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi];
1563 } else {
1564 ALOGE("Unexpected HT mcs.mcs_s index");
1565 }
1566 break;
1567 case WL_PREAMBLE_VHT:
1568 if (!mcs.mcs_s.nss)
1569 tx_rate = MCS_rate_lookup_ht[mcs.mcs_s.rate]
1570 [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi];
1571 else
1572 tx_rate = MCS_rate_lookup_ht[10+mcs.mcs_s.rate]
1573 [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi];
1574 break;
1575 default:
1576 ALOGE("Unexpected preamble");
1577 }
1578 }
1579 return tx_rate;
1580 }
1581
populate_rx_aggr_stats(hal_info * info)1582 static wifi_error populate_rx_aggr_stats(hal_info *info)
1583 {
1584 wifi_error status;
1585 wifi_ring_buffer_entry *pRingBufferEntry = info->rx_aggr_pkts;
1586 wifi_ring_per_packet_status_entry *pps_entry;
1587 u32 index = 0;
1588
1589 while ((info && !info->clean_up) && (index < info->rx_buf_size_occupied)) {
1590 pps_entry = (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
1591
1592 pps_entry->MCS = info->aggr_stats.RxMCS.mcs;
1593 pps_entry->last_transmit_rate = info->aggr_stats.last_transmit_rate;
1594 pps_entry->rssi = info->aggr_stats.rssi;
1595 pps_entry->firmware_entry_timestamp = info->aggr_stats.timestamp;
1596 pps_entry->tid = info->aggr_stats.tid;
1597
1598 index += pRingBufferEntry->entry_size;
1599 status = update_stats_to_ring_buf(info, (u8 *)pRingBufferEntry,
1600 pRingBufferEntry->entry_size);
1601
1602 if (status != WIFI_SUCCESS) {
1603 ALOGE("Failed to write Rx stats into the ring buffer");
1604 return status;
1605 }
1606 /* update_stats_to_ring_buf() modifies the size. Update the same again
1607 * here by adding sizeof(wifi_ring_buffer_entry) to continue parsing
1608 */
1609 pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)pRingBufferEntry
1610 + sizeof(wifi_ring_buffer_entry)
1611 + pRingBufferEntry->entry_size);
1612 }
1613 memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied);
1614 info->rx_buf_size_occupied = 0;
1615
1616 return WIFI_SUCCESS;
1617 }
1618
parse_rx_stats_v2(hal_info * info,u8 * buf,u16 size)1619 static wifi_error parse_rx_stats_v2(hal_info *info, u8 *buf, u16 size)
1620 {
1621 wifi_error status = WIFI_SUCCESS;
1622 rb_pkt_stats_t_v1 *rx_stats_rcvd = (rb_pkt_stats_t_v1 *)buf;
1623 wifi_ring_buffer_entry *pRingBufferEntry;
1624 u32 len_ring_buffer_entry = 0;
1625
1626 if (size < sizeof(rb_pkt_stats_t)) {
1627 ALOGE("%s Unexpected rx stats event length: %d", __FUNCTION__, size);
1628 memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied);
1629 memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats));
1630 info->rx_buf_size_occupied = 0;
1631 return WIFI_ERROR_UNKNOWN;
1632 }
1633
1634 len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry)
1635 + sizeof(wifi_ring_per_packet_status_entry)
1636 + RX_HTT_HDR_STATUS_LEN_V1;
1637
1638 if (len_ring_buffer_entry + info->rx_buf_size_occupied
1639 > info->rx_buf_size_allocated) {
1640 wifi_ring_buffer_entry *temp;
1641 temp = (wifi_ring_buffer_entry *)realloc(info->rx_aggr_pkts,
1642 len_ring_buffer_entry + info->rx_buf_size_occupied);
1643 if (temp == NULL) {
1644 ALOGE("%s: Failed to reallocate memory", __FUNCTION__);
1645 free(info->rx_aggr_pkts);
1646 info->rx_aggr_pkts = NULL;
1647 return WIFI_ERROR_OUT_OF_MEMORY;
1648 }
1649 info->rx_aggr_pkts = temp;
1650 memset((u8 *)info->rx_aggr_pkts + info->rx_buf_size_allocated, 0,
1651 len_ring_buffer_entry + info->rx_buf_size_occupied
1652 - info->rx_buf_size_allocated);
1653 info->rx_buf_size_allocated =
1654 len_ring_buffer_entry + info->rx_buf_size_occupied;
1655 }
1656
1657 pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)info->rx_aggr_pkts
1658 + info->rx_buf_size_occupied);
1659
1660 info->rx_buf_size_occupied += len_ring_buffer_entry;
1661
1662 /* Fill size of the entry in rb entry which can be used while populating
1663 * the data. Actual size that needs to be sent to ring buffer is only pps
1664 * entry size
1665 */
1666 pRingBufferEntry->entry_size = len_ring_buffer_entry;
1667 wifi_ring_per_packet_status_entry *rb_pkt_stats =
1668 (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
1669
1670 memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry));
1671
1672 /* Peer tx packet and it is an Rx packet for us */
1673 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_DIRECTION_TX;
1674
1675 if (!((rx_stats_rcvd->mpdu_end.overflow_err) ||
1676 (rx_stats_rcvd->attention.fcs_err) ||
1677 (rx_stats_rcvd->attention.mpdu_length_err) ||
1678 (rx_stats_rcvd->attention.msdu_length_err) ||
1679 (rx_stats_rcvd->attention.tkip_mic_err) ||
1680 (rx_stats_rcvd->attention.decrypt_err)))
1681 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
1682
1683 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER;
1684
1685 if (rx_stats_rcvd->mpdu_start.encrypted)
1686 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED;
1687
1688 if (rx_stats_rcvd->attention.first_mpdu) {
1689 MCS *mcs = &info->aggr_stats.RxMCS;
1690 u32 ht_vht_sig;
1691
1692 /* Flush the cached stats as this is the first MPDU. */
1693 memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats));
1694 if (rx_stats_rcvd->ppdu_start.preamble_type == PREAMBLE_L_SIG_RATE) {
1695 if (rx_stats_rcvd->ppdu_start.l_sig_rate_select) {
1696 mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_CCK;
1697 mcs->mcs_s.rate = cck_ratecode_mapping(rx_stats_rcvd->ppdu_start.l_sig_rate);
1698 } else {
1699 mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_OFDM;
1700 mcs->mcs_s.rate = ofdm_ratecode_mapping(rx_stats_rcvd->ppdu_start.l_sig_rate);
1701 }
1702 /*BW is 0 for legacy cases*/
1703 } else if (rx_stats_rcvd->ppdu_start.preamble_type ==
1704 PREAMBLE_VHT_SIG_A_1) {
1705 ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1;
1706 mcs->mcs_s.nss = ((ht_vht_sig >> 3) & 0x3);
1707 //mcs->mcs_s.nss = (ht_vht_sig & BITMASK(7)) >> 3;
1708 mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_HT;
1709 mcs->mcs_s.rate = ((ht_vht_sig & BITMASK(7)) % 8) & 0xF;
1710 mcs->mcs_s.bw = ((ht_vht_sig >> 7) & 1);
1711 mcs->mcs_s.short_gi =
1712 ((rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 7) & 1);
1713 } else if (rx_stats_rcvd->ppdu_start.preamble_type ==
1714 PREAMBLE_VHT_SIG_A_2) {
1715 ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1;
1716 mcs->mcs_s.nss = ((ht_vht_sig >> 10) & 0x3);
1717 mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_VHT;
1718 mcs->mcs_s.rate =
1719 (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 4) & BITMASK(4);
1720 mcs->mcs_s.bw = (ht_vht_sig & 3);
1721 mcs->mcs_s.short_gi =
1722 (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 & 1);
1723 }
1724
1725 info->aggr_stats.last_transmit_rate
1726 = get_rate_v1(info->aggr_stats.RxMCS.mcs);
1727
1728 info->aggr_stats.rssi = rx_stats_rcvd->ppdu_start.rssi_comb;
1729 info->aggr_stats.tid = rx_stats_rcvd->mpdu_start.tid;
1730 }
1731 rb_pkt_stats->link_layer_transmit_sequence
1732 = rx_stats_rcvd->mpdu_start.seq_num;
1733
1734 memcpy(&rb_pkt_stats->data[0], &rx_stats_rcvd->rx_hdr_status[0],
1735 RX_HTT_HDR_STATUS_LEN_V1);
1736
1737 if ((rx_stats_rcvd->attention.last_mpdu
1738 && rx_stats_rcvd->msdu_end.last_msdu)
1739 || (rx_stats_rcvd->attention.first_mpdu
1740 && rx_stats_rcvd->attention.last_mpdu)) {
1741 info->aggr_stats.timestamp = rx_stats_rcvd->ppdu_end.wb_timestamp_lower_32;
1742
1743 status = populate_rx_aggr_stats(info);
1744 }
1745
1746 return status;
1747 }
1748
parse_rx_stats(hal_info * info,u8 * buf,u16 size)1749 static wifi_error parse_rx_stats(hal_info *info, u8 *buf, u16 size)
1750 {
1751 wifi_error status = WIFI_SUCCESS;
1752 rb_pkt_stats_t *rx_stats_rcvd = (rb_pkt_stats_t *)buf;
1753 wifi_ring_buffer_entry *pRingBufferEntry;
1754 u32 len_ring_buffer_entry = 0;
1755
1756 if (size < sizeof(rb_pkt_stats_t)) {
1757 ALOGE("%s Unexpected rx stats event length: %d", __FUNCTION__, size);
1758 memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied);
1759 memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats));
1760 info->rx_buf_size_occupied = 0;
1761 return WIFI_ERROR_UNKNOWN;
1762 }
1763
1764 len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry)
1765 + sizeof(wifi_ring_per_packet_status_entry)
1766 + RX_HTT_HDR_STATUS_LEN;
1767
1768 if (len_ring_buffer_entry + info->rx_buf_size_occupied
1769 > info->rx_buf_size_allocated) {
1770 wifi_ring_buffer_entry *temp;
1771 temp = (wifi_ring_buffer_entry *)realloc(info->rx_aggr_pkts,
1772 len_ring_buffer_entry + info->rx_buf_size_occupied);
1773 if (temp == NULL) {
1774 ALOGE("%s: Failed to reallocate memory", __FUNCTION__);
1775 free(info->rx_aggr_pkts);
1776 info->rx_aggr_pkts = NULL;
1777 return WIFI_ERROR_OUT_OF_MEMORY;
1778 }
1779 info->rx_aggr_pkts = temp;
1780 memset((u8 *)info->rx_aggr_pkts + info->rx_buf_size_allocated, 0,
1781 len_ring_buffer_entry + info->rx_buf_size_occupied
1782 - info->rx_buf_size_allocated);
1783 info->rx_buf_size_allocated =
1784 len_ring_buffer_entry + info->rx_buf_size_occupied;
1785 }
1786
1787 pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)info->rx_aggr_pkts
1788 + info->rx_buf_size_occupied);
1789
1790 info->rx_buf_size_occupied += len_ring_buffer_entry;
1791
1792 /* Fill size of the entry in rb entry which can be used while populating
1793 * the data. Actual size that needs to be sent to ring buffer is only pps
1794 * entry size
1795 */
1796 pRingBufferEntry->entry_size = len_ring_buffer_entry;
1797 wifi_ring_per_packet_status_entry *rb_pkt_stats =
1798 (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
1799
1800 memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry));
1801
1802 /* Peer tx packet and it is an Rx packet for us */
1803 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_DIRECTION_TX;
1804
1805 if (!((rx_stats_rcvd->mpdu_end.overflow_err) ||
1806 (rx_stats_rcvd->attention.fcs_err) ||
1807 (rx_stats_rcvd->attention.mpdu_length_err) ||
1808 (rx_stats_rcvd->attention.msdu_length_err) ||
1809 (rx_stats_rcvd->attention.tkip_mic_err) ||
1810 (rx_stats_rcvd->attention.decrypt_err)))
1811 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
1812
1813 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER;
1814
1815 if (rx_stats_rcvd->mpdu_start.encrypted)
1816 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED;
1817
1818 if (rx_stats_rcvd->attention.first_mpdu) {
1819 MCS *mcs = &info->aggr_stats.RxMCS;
1820 u32 ht_vht_sig;
1821
1822 /* Flush the cached stats as this is the first MPDU. */
1823 memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats));
1824 if (rx_stats_rcvd->ppdu_start.preamble_type == PREAMBLE_L_SIG_RATE) {
1825 if (rx_stats_rcvd->ppdu_start.l_sig_rate_select)
1826 mcs->mcs_s.preamble = WL_PREAMBLE_OFDM;
1827 mcs->mcs_s.rate = rx_stats_rcvd->ppdu_start.l_sig_rate - 8;
1828 /*BW is 0 for legacy cases*/
1829 } else if (rx_stats_rcvd->ppdu_start.preamble_type ==
1830 PREAMBLE_VHT_SIG_A_1) {
1831 ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1;
1832 mcs->mcs_s.nss = ((ht_vht_sig >> 3) & 0x3);
1833 mcs->mcs_s.preamble = WL_PREAMBLE_HT;
1834 mcs->mcs_s.rate = (ht_vht_sig & BITMASK(7)) >> 3;
1835 mcs->mcs_s.bw = ((ht_vht_sig >> 7) & 1);
1836 mcs->mcs_s.short_gi =
1837 ((rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 7) & 1);
1838 } else if (rx_stats_rcvd->ppdu_start.preamble_type ==
1839 PREAMBLE_VHT_SIG_A_2) {
1840 ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1;
1841 mcs->mcs_s.nss = ((ht_vht_sig >> 10) & 0x3);
1842 mcs->mcs_s.preamble = WL_PREAMBLE_VHT;
1843 mcs->mcs_s.rate =
1844 (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 4) & BITMASK(4);
1845 mcs->mcs_s.bw = (ht_vht_sig & 3);
1846 mcs->mcs_s.short_gi =
1847 (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 & 1);
1848 }
1849
1850 info->aggr_stats.last_transmit_rate
1851 = get_rate(info->aggr_stats.RxMCS.mcs);
1852
1853 info->aggr_stats.rssi = rx_stats_rcvd->ppdu_start.rssi_comb;
1854 info->aggr_stats.tid = rx_stats_rcvd->mpdu_start.tid;
1855 }
1856 rb_pkt_stats->link_layer_transmit_sequence
1857 = rx_stats_rcvd->mpdu_start.seq_num;
1858
1859 memcpy(&rb_pkt_stats->data[0], &rx_stats_rcvd->rx_hdr_status[0],
1860 RX_HTT_HDR_STATUS_LEN);
1861
1862 if ((rx_stats_rcvd->attention.last_mpdu
1863 && rx_stats_rcvd->msdu_end.last_msdu)
1864 || (rx_stats_rcvd->attention.first_mpdu
1865 && rx_stats_rcvd->attention.last_mpdu)) {
1866 info->aggr_stats.timestamp = rx_stats_rcvd->ppdu_end.tsf_timestamp;
1867 status = populate_rx_aggr_stats(info);
1868 }
1869
1870 return status;
1871 }
1872
get_tx_mcs_v1(u8 * data)1873 static u16 get_tx_mcs_v1(u8 *data)
1874 {
1875 MCS mcs;
1876 RATE_CODE rate_code;
1877 u16 extended_flags;
1878 mcs.mcs = 0;
1879
1880 rate_code = *((RATE_CODE*)(data + RATE_CODE_OFFSET));
1881 extended_flags = *((u16*)(data + EXT_FLAGS_OFFSET));
1882
1883 mcs.mcs_s.rate = rate_code.rateCode & 0xF;
1884 mcs.mcs_s.nss = (rate_code.rateCode >> 4) & 0x3;
1885 mcs.mcs_s.preamble = (rate_code.rateCode >> 6) & 0x3;
1886 mcs.mcs_s.short_gi = (((extended_flags >> 12) & 0x1) == 1) ? 1 : 0;
1887 mcs.mcs_s.bw = (rate_code.flags >> 5) & 0x3;
1888
1889 return mcs.mcs;
1890 }
1891
get_tx_mcs(u8 series,struct tx_ppdu_start * ppdu_start)1892 static u16 get_tx_mcs(u8 series,
1893 struct tx_ppdu_start *ppdu_start)
1894 {
1895 MCS mcs;
1896 struct series_bw *sbw = NULL;
1897
1898 mcs.mcs = 0;
1899
1900 if (series == 0) {
1901 if (ppdu_start->valid_s0_bw20)
1902 sbw = &ppdu_start->s0_bw20;
1903 else if (ppdu_start->valid_s0_bw40)
1904 sbw = &ppdu_start->s0_bw40;
1905 else if (ppdu_start->valid_s0_bw80)
1906 sbw = &ppdu_start->s0_bw80;
1907 else if (ppdu_start->valid_s0_bw160)
1908 sbw = &ppdu_start->s0_bw160;
1909 } else {
1910 if (ppdu_start->valid_s1_bw20)
1911 sbw = &ppdu_start->s1_bw20;
1912 else if (ppdu_start->valid_s1_bw40)
1913 sbw = &ppdu_start->s1_bw40;
1914 else if (ppdu_start->valid_s1_bw80)
1915 sbw = &ppdu_start->s1_bw80;
1916 else if (ppdu_start->valid_s1_bw160)
1917 sbw = &ppdu_start->s1_bw160;
1918 }
1919
1920 if (sbw) {
1921 mcs.mcs_s.rate = sbw->rate;
1922 mcs.mcs_s.nss = sbw->nss;
1923 mcs.mcs_s.preamble = sbw->preamble_type;
1924 mcs.mcs_s.short_gi = sbw->short_gi;
1925 }
1926
1927 return mcs.mcs;
1928 }
1929
get_tx_aggr_stats(struct tx_ppdu_start * ppdu_start,hal_info * info)1930 static void get_tx_aggr_stats(struct tx_ppdu_start *ppdu_start, hal_info *info)
1931 {
1932 u32 baBitmap0 = 0;
1933 u32 baBitmap1 = 0;
1934
1935 info->pkt_stats->tx_seqnum_bitmap_31_0 = ppdu_start->seqnum_bitmap_31_0;
1936 info->pkt_stats->tx_seqnum_bitmap_63_32 = ppdu_start->seqnum_bitmap_63_32;
1937
1938 if (info->pkt_stats->isBlockAck) {
1939 int baShift = ppdu_start->start_seq_num - info->pkt_stats->ba_seq_num;
1940 //There are 4 scenarios in total:
1941 //1.TxSeq No. >= BaSeq No. and no roll over.
1942 //2.TxSeq No. >= BaSeq No. and TxSeq No. rolls over.
1943 //3.TxSeq No. <= BaSeq No. and no roll over.
1944 //4.TxSeq No. <= BaSeq No. and BaSeq No. rolls over.
1945
1946 baBitmap0 = info->pkt_stats->ba_bitmap_31_0;
1947 baBitmap1 = info->pkt_stats->ba_bitmap_63_32;
1948
1949 if (((baShift >= 0) && (baShift < SEQ_NUM_RANGE/2)) ||
1950 (baShift < -SEQ_NUM_RANGE/2)) {
1951 //Scenario No.1 and No.2
1952 baShift = baShift < -SEQ_NUM_RANGE/2 ? (SEQ_NUM_RANGE + baShift) :
1953 baShift;
1954
1955 if (baShift < BITMAP_VAR_SIZE) {
1956 info->pkt_stats->shifted_bitmap_31_0 =
1957 ((baBitmap1 << (32 - baShift)) | (baBitmap0 >> baShift));
1958 info->pkt_stats->shifted_bitmap_63_32 = baBitmap1 >> baShift;
1959 } else {
1960 info->pkt_stats->shifted_bitmap_31_0 =
1961 baBitmap1 >> (baShift - BITMAP_VAR_SIZE);
1962 info->pkt_stats->shifted_bitmap_63_32 = 0;
1963 }
1964 } else {
1965 baShift = (baShift >= SEQ_NUM_RANGE/2) ? (SEQ_NUM_RANGE - baShift) :
1966 -baShift;
1967 if (baShift < BITMAP_VAR_SIZE) {
1968 info->pkt_stats->shifted_bitmap_31_0 = baBitmap0 << baShift;
1969 info->pkt_stats->shifted_bitmap_63_32 =
1970 ((baBitmap0 << (32 - baShift)) |
1971 (baBitmap1 >> baShift));
1972 } else {
1973 info->pkt_stats->shifted_bitmap_31_0 = 0;
1974 info->pkt_stats->shifted_bitmap_63_32 =
1975 baBitmap0 << (baShift - BITMAP_VAR_SIZE);
1976 }
1977 }
1978 } else {
1979 info->pkt_stats->shifted_bitmap_31_0 = 0;
1980 info->pkt_stats->shifted_bitmap_63_32 = 0;
1981 }
1982 }
1983
get_try_status_params(hal_info * info,struct tx_ppdu_end * tx_ppdu_end)1984 static void get_try_status_params(hal_info *info,
1985 struct tx_ppdu_end *tx_ppdu_end)
1986 {
1987 int try_list_index;
1988
1989 if (tx_ppdu_end->stat.total_tries > 0)
1990 try_list_index = tx_ppdu_end->stat.total_tries - 1;
1991 else
1992 try_list_index = 0;
1993
1994 info->pkt_stats->tx_bandwidth =
1995 tx_ppdu_end->try_list.try_st[try_list_index].packet_bw;
1996 info->pkt_stats->series =
1997 tx_ppdu_end->try_list.try_st[try_list_index].series;
1998 }
1999
parse_tx_stats(hal_info * info,void * buf,u32 buflen,u8 logtype)2000 static wifi_error parse_tx_stats(hal_info *info, void *buf,
2001 u32 buflen, u8 logtype)
2002 {
2003 wifi_error status = WIFI_SUCCESS;
2004 int i;
2005 wifi_ring_buffer_entry *pRingBufferEntry =
2006 (wifi_ring_buffer_entry *)info->pkt_stats->tx_stats;
2007
2008 wifi_ring_per_packet_status_entry *rb_pkt_stats =
2009 (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
2010
2011 ALOGV("Received Tx stats: log_type : %d", logtype);
2012 switch (logtype)
2013 {
2014 case PKTLOG_TYPE_TX_CTRL:
2015 {
2016 if (buflen < sizeof (wh_pktlog_txctl)) {
2017 ALOGE("Unexpected tx_ctrl event length: %d", buflen);
2018 return WIFI_ERROR_UNKNOWN;
2019 }
2020
2021 wh_pktlog_txctl *stats = (wh_pktlog_txctl *)buf;
2022 struct tx_ppdu_start *ppdu_start =
2023 (struct tx_ppdu_start *)(&stats->u.ppdu_start);
2024
2025 if (ppdu_start->frame_control & BIT(DATA_PROTECTED))
2026 rb_pkt_stats->flags |=
2027 PER_PACKET_ENTRY_FLAGS_PROTECTED;
2028 rb_pkt_stats->link_layer_transmit_sequence
2029 = ppdu_start->start_seq_num;
2030 info->pkt_stats->start_seq_num = ppdu_start->start_seq_num;
2031 rb_pkt_stats->tid = ppdu_start->qos_ctl & 0xF;
2032 rb_pkt_stats->MCS = get_tx_mcs(info->pkt_stats->series, ppdu_start) |
2033 (info->pkt_stats->tx_bandwidth << BW_OFFSET);
2034 rb_pkt_stats->last_transmit_rate = get_rate(rb_pkt_stats->MCS);
2035
2036 if (ppdu_start->ampdu)
2037 get_tx_aggr_stats(ppdu_start, info);
2038 info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_CTRL);
2039 }
2040 break;
2041 case PKTLOG_TYPE_TX_STAT:
2042 {
2043 if (buflen < sizeof(struct tx_ppdu_end)) {
2044 ALOGE("Unexpected tx_stat event length: %d", buflen);
2045 return WIFI_ERROR_UNKNOWN;
2046 }
2047
2048 /* This should be the first event for tx-stats: So,
2049 * previous stats are invalid. Flush the old stats and treat
2050 * this as new packet
2051 */
2052 if (info->pkt_stats->tx_stats_events)
2053 memset(rb_pkt_stats, 0,
2054 sizeof(wifi_ring_per_packet_status_entry));
2055
2056 struct tx_ppdu_end *tx_ppdu_end = (struct tx_ppdu_end*)(buf);
2057
2058 info->pkt_stats->ba_seq_num = tx_ppdu_end->stat.ba_start_seq_num;
2059 info->pkt_stats->isBlockAck = tx_ppdu_end->stat.ba_status;
2060
2061 if (tx_ppdu_end->stat.tx_ok)
2062 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
2063 info->pkt_stats->isBlockAck = tx_ppdu_end->stat.ba_status;
2064
2065 info->pkt_stats->ba_bitmap_31_0 = tx_ppdu_end->stat.ba_bitmap_31_0;
2066 info->pkt_stats->ba_bitmap_63_32 =
2067 tx_ppdu_end->stat.ba_bitmap_63_32;
2068 rb_pkt_stats->transmit_success_timestamp =
2069 tx_ppdu_end->try_list.try_st[0].timestamp;
2070 rb_pkt_stats->rssi = tx_ppdu_end->stat.ack_rssi_ave;
2071 rb_pkt_stats->num_retries = tx_ppdu_end->stat.total_tries;
2072 get_try_status_params(info, tx_ppdu_end);
2073
2074 info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_STAT);
2075 }
2076 break;
2077 case PKTLOG_TYPE_TX_MSDU_ID:
2078 {
2079 memset(info->pkt_stats, 0, sizeof(struct pkt_stats_s));
2080 info->pkt_stats->num_msdu = *(u8 *)buf;
2081 info->pkt_stats->tx_stats_events = BIT(PKTLOG_TYPE_TX_MSDU_ID);
2082 }
2083 break;
2084 case PKTLOG_TYPE_RC_UPDATE:
2085 case PKTLOG_TYPE_TX_FRM_HDR:
2086 case PKTLOG_TYPE_RC_FIND:
2087 case PKTLOG_TYPE_TX_VIRT_ADDR:
2088 ALOGV("%s : Unsupported log_type received : %d",
2089 __FUNCTION__, logtype);
2090 break;
2091 default:
2092 {
2093 ALOGV("%s : Unexpected log_type received : %d",
2094 __FUNCTION__, logtype);
2095 return WIFI_ERROR_UNKNOWN;
2096 }
2097 }
2098
2099 if ((info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_CTRL)) &&
2100 (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_STAT)) &&
2101 (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_MSDU_ID))) {
2102 /* No tx payload as of now, add the length to parameter size(3rd)
2103 * if there is any payload
2104 */
2105
2106 if (info->pkt_stats->num_msdu == 1) {
2107 if (!(rb_pkt_stats->flags & PER_PACKET_ENTRY_FLAGS_TX_SUCCESS))
2108 rb_pkt_stats->rssi = INVALID_RSSI;
2109 /* Handle non aggregated cases */
2110 status = update_stats_to_ring_buf(info,
2111 (u8 *)pRingBufferEntry,
2112 sizeof(wifi_ring_buffer_entry) +
2113 sizeof(wifi_ring_per_packet_status_entry));
2114 if (status != WIFI_SUCCESS) {
2115 ALOGE("Failed to write into the ring buffer : %d", logtype);
2116 }
2117 } else {
2118 /* Handle aggregated cases */
2119 for (i = 0; i < MAX_BA_WINDOW_SIZE; i++) {
2120 if (i < BITMAP_VAR_SIZE) {
2121 if (info->pkt_stats->tx_seqnum_bitmap_31_0 & BIT(i)) {
2122 if (info->pkt_stats->shifted_bitmap_31_0 & BIT(i)) {
2123 rb_pkt_stats->flags |=
2124 PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
2125 } else {
2126 rb_pkt_stats->flags &=
2127 ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
2128 rb_pkt_stats->rssi = INVALID_RSSI;
2129 }
2130 } else {
2131 continue;
2132 }
2133 } else {
2134 if (info->pkt_stats->tx_seqnum_bitmap_63_32
2135 & BIT(i - BITMAP_VAR_SIZE)) {
2136 if (info->pkt_stats->shifted_bitmap_63_32
2137 & BIT(i - BITMAP_VAR_SIZE)) {
2138 rb_pkt_stats->flags |=
2139 PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
2140 } else {
2141 rb_pkt_stats->flags &=
2142 ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
2143 rb_pkt_stats->rssi = INVALID_RSSI;
2144 }
2145 } else {
2146 continue;
2147 }
2148 }
2149 rb_pkt_stats->link_layer_transmit_sequence =
2150 info->pkt_stats->start_seq_num + i;
2151
2152 /* Take care of roll over SEQ_NUM_RANGE */
2153 rb_pkt_stats->link_layer_transmit_sequence &= 0xFFF;
2154
2155 status = update_stats_to_ring_buf(info,
2156 (u8 *)pRingBufferEntry,
2157 sizeof(wifi_ring_buffer_entry) +
2158 sizeof(wifi_ring_per_packet_status_entry));
2159 if (status != WIFI_SUCCESS) {
2160 ALOGE("Failed to write into the ring buffer: %d", logtype);
2161 break;
2162 }
2163 }
2164 }
2165
2166 /* Flush the local copy after writing the stats to ring buffer
2167 * for tx-stats.
2168 */
2169 info->pkt_stats->tx_stats_events = 0;
2170 memset(rb_pkt_stats, 0,
2171 sizeof(wifi_ring_per_packet_status_entry));
2172
2173 }
2174
2175 return status;
2176 }
2177
write_per_packet_stats_to_rb(hal_info * info,u8 * buf,u16 length)2178 wifi_error write_per_packet_stats_to_rb(hal_info *info, u8 *buf, u16 length)
2179 {
2180 wifi_ring_buffer_entry rb_entry_hdr;
2181 struct timeval time;
2182 wifi_error status;
2183
2184 rb_entry_hdr.entry_size = length;
2185 rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
2186 rb_entry_hdr.type = ENTRY_TYPE_PKT;
2187 gettimeofday(&time, NULL);
2188 rb_entry_hdr.timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
2189
2190 /* Write if verbose and handler is set */
2191 if (info->rb_infos[PKT_STATS_RB_ID].verbose_level >= VERBOSE_REPRO_PROBLEM &&
2192 info->on_ring_buffer_data) {
2193 /* Write header and payload separately to avoid
2194 * complete payload memcpy */
2195 status = ring_buffer_write(&info->rb_infos[PKT_STATS_RB_ID],
2196 (u8*)&rb_entry_hdr,
2197 sizeof(wifi_ring_buffer_entry),
2198 0,
2199 sizeof(wifi_ring_buffer_entry) + length);
2200 if (status != WIFI_SUCCESS) {
2201 ALOGE("Failed to write driver prints rb header %d", status);
2202 return status;
2203 }
2204 status = ring_buffer_write(&info->rb_infos[PKT_STATS_RB_ID],
2205 buf,
2206 length,
2207 1,
2208 length);
2209 if (status != WIFI_SUCCESS) {
2210 ALOGE("Failed to write PKT stats into the ring buffer");
2211 }
2212 }
2213
2214 return WIFI_SUCCESS;
2215 }
2216
parse_tx_pkt_fate_stats(hal_info * info,u8 * buf,u16 size)2217 static wifi_error parse_tx_pkt_fate_stats(hal_info *info, u8 *buf, u16 size)
2218 {
2219 pktdump_hdr *log = (pktdump_hdr *)buf;
2220 wifi_tx_report_i *pkt_fate_stats;
2221
2222 if (info->pkt_fate_stats->n_tx_stats_collected >= MAX_FATE_LOG_LEN) {
2223 ALOGD("Only %u events are expected, don't process this event",
2224 MAX_FATE_LOG_LEN);
2225 return WIFI_SUCCESS;
2226 }
2227
2228 pkt_fate_stats = &info->pkt_fate_stats->tx_fate_stats[
2229 info->pkt_fate_stats->n_tx_stats_collected];
2230
2231 pkt_fate_stats->fate = (wifi_tx_packet_fate)log->status;
2232 if (log->type == TX_MGMT_PKT)
2233 pkt_fate_stats->frame_inf.payload_type = FRAME_TYPE_80211_MGMT;
2234 else
2235 pkt_fate_stats->frame_inf.payload_type = FRAME_TYPE_ETHERNET_II;
2236
2237 pkt_fate_stats->frame_inf.driver_timestamp_usec = log->driver_ts;
2238 pkt_fate_stats->frame_inf.firmware_timestamp_usec = log->fw_ts;
2239 pkt_fate_stats->frame_inf.frame_len = size - sizeof(pktdump_hdr);
2240 pkt_fate_stats->frame_inf.frame_content =
2241 (char *)malloc(pkt_fate_stats->frame_inf.frame_len * sizeof(char));
2242 if (pkt_fate_stats->frame_inf.frame_content) {
2243 memcpy(pkt_fate_stats->frame_inf.frame_content,
2244 buf + sizeof(pktdump_hdr), pkt_fate_stats->frame_inf.frame_len);
2245 } else {
2246 ALOGE("Failed to allocate mem for Tx frame_content for packet: %zu",
2247 info->pkt_fate_stats->n_tx_stats_collected);
2248 pkt_fate_stats->frame_inf.frame_len = 0;
2249 }
2250
2251 info->pkt_fate_stats->n_tx_stats_collected++;
2252
2253 return WIFI_SUCCESS;
2254 }
2255
2256
parse_rx_pkt_fate_stats(hal_info * info,u8 * buf,u16 size)2257 static wifi_error parse_rx_pkt_fate_stats(hal_info *info, u8 *buf, u16 size)
2258 {
2259 pktdump_hdr *log = (pktdump_hdr *)buf;
2260 wifi_rx_report_i *pkt_fate_stats;
2261
2262 if (info->pkt_fate_stats->n_rx_stats_collected >= MAX_FATE_LOG_LEN) {
2263 ALOGD("Only %u events are expected, don't process this event",
2264 MAX_FATE_LOG_LEN);
2265 return WIFI_SUCCESS;
2266 }
2267
2268 pkt_fate_stats = &info->pkt_fate_stats->rx_fate_stats[
2269 info->pkt_fate_stats->n_rx_stats_collected];
2270
2271 pkt_fate_stats->fate = (wifi_rx_packet_fate)log->status;
2272 if (log->type == RX_MGMT_PKT)
2273 pkt_fate_stats->frame_inf.payload_type = FRAME_TYPE_80211_MGMT;
2274 else
2275 pkt_fate_stats->frame_inf.payload_type = FRAME_TYPE_ETHERNET_II;
2276
2277 pkt_fate_stats->frame_inf.driver_timestamp_usec = log->driver_ts;
2278 pkt_fate_stats->frame_inf.firmware_timestamp_usec = log->fw_ts;
2279 pkt_fate_stats->frame_inf.frame_len = size - sizeof(pktdump_hdr);
2280 pkt_fate_stats->frame_inf.frame_content =
2281 (char *)malloc(pkt_fate_stats->frame_inf.frame_len * sizeof(char));
2282 if (pkt_fate_stats->frame_inf.frame_content) {
2283 memcpy(pkt_fate_stats->frame_inf.frame_content,
2284 buf + sizeof(pktdump_hdr), pkt_fate_stats->frame_inf.frame_len);
2285 } else {
2286 ALOGE("Failed to allocate mem for Rx frame_content for packet: %zu",
2287 info->pkt_fate_stats->n_rx_stats_collected);
2288 pkt_fate_stats->frame_inf.frame_len = 0;
2289 }
2290
2291 info->pkt_fate_stats->n_rx_stats_collected++;
2292
2293 return WIFI_SUCCESS;
2294 }
2295
2296
trigger_fate_stats(hal_info * info,u8 * buf,u16 size)2297 static wifi_error trigger_fate_stats(hal_info *info, u8 *buf, u16 size)
2298 {
2299 int i;
2300 packet_fate_monitor_info *pkt_fate_stats = info->pkt_fate_stats;
2301
2302 for (i=0; i<MAX_FATE_LOG_LEN; i++) {
2303 if (pkt_fate_stats->tx_fate_stats[i].frame_inf.frame_content) {
2304 free (pkt_fate_stats->tx_fate_stats[i].frame_inf.frame_content);
2305 pkt_fate_stats->tx_fate_stats[i].frame_inf.frame_content = NULL;
2306 }
2307
2308 if (pkt_fate_stats->rx_fate_stats[i].frame_inf.frame_content) {
2309 free (pkt_fate_stats->rx_fate_stats[i].frame_inf.frame_content);
2310 pkt_fate_stats->rx_fate_stats[i].frame_inf.frame_content = NULL;
2311 }
2312 }
2313 memset(pkt_fate_stats, 0, sizeof(packet_fate_monitor_info));
2314
2315 return WIFI_SUCCESS;
2316 }
2317
2318
report_fate_stats(hal_info * info,u8 * buf,u16 size)2319 static wifi_error report_fate_stats(hal_info *info, u8 *buf, u16 size)
2320 {
2321 ALOGI("Fate Tx-Rx: Packet fate stats stop received");
2322 return WIFI_SUCCESS;
2323 }
2324
2325
parse_pkt_fate_stats(hal_info * info,u8 * buf,u16 size)2326 static wifi_error parse_pkt_fate_stats(hal_info *info, u8 *buf, u16 size)
2327 {
2328 pktdump_hdr *hdr = (pktdump_hdr *)buf;
2329
2330 switch (hdr->type)
2331 {
2332 case START_MONITOR:
2333 trigger_fate_stats(info, buf, size);
2334 break;
2335 case STOP_MONITOR:
2336 report_fate_stats(info, buf, size);
2337 break;
2338 case TX_MGMT_PKT:
2339 case TX_DATA_PKT:
2340 parse_tx_pkt_fate_stats(info, buf, size);
2341 break;
2342 case RX_MGMT_PKT:
2343 case RX_DATA_PKT:
2344 parse_rx_pkt_fate_stats(info, buf, size);
2345 break;
2346 default:
2347 ALOGE("Unsupported type : %d", hdr->type);
2348 return WIFI_ERROR_INVALID_ARGS;
2349 }
2350 return WIFI_SUCCESS;
2351 }
2352
2353 /*
2354 * ---------------------------------------------------------------------------------
2355 * | pkt log | packet log data contain sub packet log info |
2356 * | header |------------------------------------------------------------------|
2357 * | | sub pkt log | sub pkt log | sub pkt log | sub pkt log | |
2358 * | | header | data | header | data |..... |
2359 * |--------------------------------------------------------------------------------
2360 */
parse_stats_sw_event(hal_info * info,wh_pktlog_hdr_v2_t * pkt_stats_header)2361 static wifi_error parse_stats_sw_event(hal_info *info,
2362 wh_pktlog_hdr_v2_t *pkt_stats_header)
2363 {
2364 u32 pkt_stats_len;
2365 int num_of_node = 0;
2366 u8 *data;
2367 u8 *node_pkt_data;
2368 wh_pktlog_hdr_v2_t *pkt_stats_node_header;
2369 int node_pkt_type,pkt_sub_type,node_pkt_len,i;
2370 wifi_error status = WIFI_SUCCESS;
2371 node_pkt_stats node_pkt_t;
2372 wifi_ring_buffer_entry *pRingBufferEntry =
2373 (wifi_ring_buffer_entry *)info->pkt_stats->tx_stats;
2374
2375 wifi_ring_per_packet_status_entry *rb_pkt_stats =
2376 (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
2377
2378 pkt_stats_len = pkt_stats_header->size;
2379 data = ((u8 *)pkt_stats_header + sizeof(wh_pktlog_hdr_v2_t));
2380 num_of_node = (pkt_stats_header->reserved >> 16) & 0xFFFF;
2381 pkt_sub_type = pkt_stats_header->reserved & 0xFFFF;
2382
2383 do {
2384 if (pkt_stats_len < sizeof(wh_pktlog_hdr_v2_t)) {
2385 status = WIFI_ERROR_INVALID_ARGS;
2386 break;
2387 }
2388 if (pkt_sub_type == 1) {
2389 pkt_stats_node_header = (wh_pktlog_hdr_v2_t *)data;
2390 if (pkt_stats_node_header) {
2391 node_pkt_type = pkt_stats_node_header->log_type;
2392 node_pkt_len = pkt_stats_node_header->size;
2393 node_pkt_data = ((u8 *)pkt_stats_node_header + sizeof(wh_pktlog_hdr_v2_t));
2394 switch (node_pkt_type) {
2395 case PKTLOG_TYPE_TX_CTRL:
2396 info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_CTRL);
2397 break;
2398 case PKTLOG_TYPE_TX_STAT:
2399 {
2400 memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry));
2401 memset(&node_pkt_t, 0, sizeof(node_pkt_stats));
2402 node_pkt_t.frm_ctrl = *((u16*)(node_pkt_data + FRAME_CTRL_OFFSET));
2403 if (node_pkt_t.frm_ctrl & BIT(DATA_PROTECTED))
2404 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED;
2405 rb_pkt_stats->transmit_success_timestamp =
2406 *((u64*)(node_pkt_data + TX_SUCCESS_TMS_OFFSET));
2407 rb_pkt_stats->link_layer_transmit_sequence =
2408 *((u16*)(node_pkt_data + LINK_LAYER_TX_SQN_OFFSET));
2409 node_pkt_t.tx_ok = *((u8*)(node_pkt_data + TX_STATUS_OFFSET));
2410 if (node_pkt_t.tx_ok == 0)
2411 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
2412 rb_pkt_stats->rssi = *((u8*)(node_pkt_data + TX_RSSI_OFFSET));
2413 rb_pkt_stats->num_retries = *((u8*)(node_pkt_data + NO_RETRIES_OFFSET));
2414 node_pkt_t.qos_ctrl = *((u8*)(node_pkt_data + QOS_CTRL_OFFSET));
2415 rb_pkt_stats->tid = node_pkt_t.qos_ctrl & 0xF;
2416 rb_pkt_stats->MCS = get_tx_mcs_v1(node_pkt_data);
2417 if ((rb_pkt_stats->MCS & INVALID_RATE_CODE) != INVALID_RATE_CODE)
2418 rb_pkt_stats->last_transmit_rate = get_rate_v1(rb_pkt_stats->MCS);
2419 node_pkt_t.bmap_failed = *((u64*)(node_pkt_data + BMAP_FAILED_OFFSET));
2420 node_pkt_t.bmap_enqueued = *((u64*)(node_pkt_data + BMAP_ENQUEUED_OFFSET));
2421
2422 info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_STAT);
2423 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER;
2424 }
2425 break;
2426 default:
2427 // TODO: Unexpected PKTLOG types
2428 break;
2429 }
2430 if (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_STAT)) {
2431 /* if bmap_enqueued is 1 ,Handle non aggregated cases */
2432 if (node_pkt_t.bmap_enqueued == 1) {
2433 status = update_stats_to_ring_buf(info,
2434 (u8 *)pRingBufferEntry,
2435 sizeof(wifi_ring_buffer_entry) +
2436 sizeof(wifi_ring_per_packet_status_entry));
2437 if (status != WIFI_SUCCESS) {
2438 ALOGE("Failed to write into the ring buffer : %d", node_pkt_type);
2439 }
2440 } else {
2441 /* if bmap_enqueued is more than 1 ,Handle aggregated cases */
2442 for (i = 0; i < MAX_BA_WINDOW_SIZE; i++) {
2443 if (((node_pkt_t.bmap_enqueued >> i) & 0x1) == 1) {
2444 if (((node_pkt_t.bmap_failed >> i) & 0x1) == 1) {
2445 rb_pkt_stats->flags &= ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
2446 } else {
2447 rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
2448 }
2449 status = update_stats_to_ring_buf(info,
2450 (u8 *)pRingBufferEntry,
2451 sizeof(wifi_ring_buffer_entry) +
2452 sizeof(wifi_ring_per_packet_status_entry));
2453 if (status != WIFI_SUCCESS) {
2454 ALOGE("Failed to write into the ring buffer : %d", node_pkt_type);
2455 break;
2456 }
2457 rb_pkt_stats->link_layer_transmit_sequence += 1;
2458 }
2459 }
2460 }
2461 }
2462 }
2463 pkt_stats_len = (pkt_stats_len - (sizeof(wh_pktlog_hdr_v2_t) + node_pkt_len));
2464 data = (u8*) (data + sizeof(wh_pktlog_hdr_v2_t) + node_pkt_len);
2465 info->pkt_stats->tx_stats_events = 0;
2466 }
2467 } while ((info && !info->clean_up) && (pkt_stats_len > 0));
2468 return status;
2469 }
2470
2471 /* Added This function to parse stats based on PKT_LOG_V2 Version */
parse_stats_record_v2(hal_info * info,wh_pktlog_hdr_v2_t * pkt_stats_header)2472 static wifi_error parse_stats_record_v2(hal_info *info,
2473 wh_pktlog_hdr_v2_t *pkt_stats_header)
2474 {
2475 wifi_error status = WIFI_SUCCESS;
2476
2477 if (pkt_stats_header->log_type == PKTLOG_TYPE_RX_STAT) {
2478 /* Ignore the event if it doesn't carry RX descriptor */
2479 if (pkt_stats_header->flags & PKT_INFO_FLG_RX_RXDESC_MASK)
2480 status = parse_rx_stats_v2(info,
2481 (u8 *)(pkt_stats_header + 1),
2482 pkt_stats_header->size);
2483 else
2484 status = WIFI_SUCCESS;
2485 } else if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_DUMP_V2) {
2486 pthread_mutex_lock(&info->pkt_fate_stats_lock);
2487 if (info->fate_monitoring_enabled) {
2488 if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2)
2489 status = parse_pkt_fate_stats(info,
2490 (u8 *)pkt_stats_header + sizeof(wh_pktlog_hdr_v2_t),
2491 pkt_stats_header->size);
2492 else
2493 status = WIFI_SUCCESS;
2494 } else
2495 status = WIFI_SUCCESS;
2496 pthread_mutex_unlock(&info->pkt_fate_stats_lock);
2497 } else if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_SW_EVENT) {
2498 status = parse_stats_sw_event(info, pkt_stats_header);
2499 } else
2500 ALOGE("%s: invalid log_type %d",__FUNCTION__, pkt_stats_header->log_type);
2501
2502 return status;
2503 }
2504
parse_stats_record_v1(hal_info * info,wh_pktlog_hdr_t * pkt_stats_header)2505 static wifi_error parse_stats_record_v1(hal_info *info,
2506 wh_pktlog_hdr_t *pkt_stats_header)
2507 {
2508 wifi_error status;
2509 if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_STATS) {
2510 status = write_per_packet_stats_to_rb(info,
2511 (u8 *)(pkt_stats_header + 1),
2512 pkt_stats_header->size);
2513 } else if (pkt_stats_header->log_type == PKTLOG_TYPE_RX_STAT) {
2514 /* Ignore the event if it doesn't carry RX descriptor */
2515 if (pkt_stats_header->flags & PKT_INFO_FLG_RX_RXDESC_MASK)
2516 status = parse_rx_stats(info,
2517 (u8 *)(pkt_stats_header + 1),
2518 pkt_stats_header->size);
2519 else
2520 status = WIFI_SUCCESS;
2521 } else if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_DUMP ||
2522 pkt_stats_header->log_type == PKTLOG_TYPE_PKT_DUMP_V2) {
2523 pthread_mutex_lock(&info->pkt_fate_stats_lock);
2524 if (info->fate_monitoring_enabled) {
2525 if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2)
2526 status = parse_pkt_fate_stats(info,
2527 (u8 *)pkt_stats_header + sizeof(wh_pktlog_hdr_v2_t),
2528 pkt_stats_header->size);
2529 else
2530 status = parse_pkt_fate_stats(info,
2531 (u8 *)pkt_stats_header + sizeof(wh_pktlog_hdr_t),
2532 pkt_stats_header->size);
2533 } else
2534 status = WIFI_SUCCESS;
2535 pthread_mutex_unlock(&info->pkt_fate_stats_lock);
2536 } else {
2537 status = parse_tx_stats(info,
2538 (u8 *)(pkt_stats_header + 1),
2539 pkt_stats_header->size,
2540 pkt_stats_header->log_type);
2541 }
2542 return status;
2543 }
2544
parse_stats(hal_info * info,u8 * data,u32 buflen)2545 static wifi_error parse_stats(hal_info *info, u8 *data, u32 buflen)
2546 {
2547 wh_pktlog_hdr_t *pkt_stats_header;
2548 wh_pktlog_hdr_v2_t *pkt_stats_header_v2_t;
2549 wifi_error status = WIFI_SUCCESS;
2550
2551 do {
2552 u32 record_len;
2553
2554 if (buflen < sizeof(wh_pktlog_hdr_t)) {
2555 status = WIFI_ERROR_INVALID_ARGS;
2556 break;
2557 }
2558
2559 pkt_stats_header = (wh_pktlog_hdr_t *)data;
2560 pkt_stats_header_v2_t = (wh_pktlog_hdr_v2_t *)data;
2561
2562 if (info->pkt_log_ver == PKT_LOG_V2) {
2563 if (buflen < sizeof(wh_pktlog_hdr_v2_t)) {
2564 status = WIFI_ERROR_INVALID_ARGS;
2565 break;
2566 }
2567 record_len = (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header_v2_t->size);
2568 } else {
2569 if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2){
2570 if (buflen < sizeof(wh_pktlog_hdr_v2_t)) {
2571 status = WIFI_ERROR_INVALID_ARGS;
2572 break;
2573 }
2574 record_len = (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header_v2_t->size);
2575 } else {
2576 record_len = (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size);
2577 }
2578 }
2579
2580 if (buflen < record_len) {
2581 status = WIFI_ERROR_INVALID_ARGS;
2582 break;
2583 }
2584 /* Pkt_log_V2 based packet parsing */
2585 if (info->pkt_log_ver == PKT_LOG_V2) {
2586 status = parse_stats_record_v2(info, pkt_stats_header_v2_t);
2587 if (status != WIFI_SUCCESS) {
2588 ALOGE("Failed to parse the stats type : %d",
2589 pkt_stats_header_v2_t->log_type);
2590 return status;
2591 }
2592 /* Pkt_log_V1 based packet parsing */
2593 } else {
2594 status = parse_stats_record_v1(info, pkt_stats_header);
2595 if (status != WIFI_SUCCESS) {
2596 ALOGE("Failed to parse the stats type : %d",
2597 pkt_stats_header->log_type);
2598 return status;
2599 }
2600 }
2601 data += record_len;
2602 buflen -= record_len;
2603
2604 } while ((info && !info->clean_up) && (buflen > 0));
2605
2606 return status;
2607 }
2608
process_driver_prints(hal_info * info,u8 * buf,u16 length)2609 wifi_error process_driver_prints(hal_info *info, u8 *buf, u16 length)
2610 {
2611 wifi_ring_buffer_entry rb_entry_hdr;
2612 struct timeval time;
2613 wifi_error status;
2614
2615 rb_entry_hdr.entry_size = length;
2616 rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
2617 rb_entry_hdr.type = ENTRY_TYPE_DATA;
2618 gettimeofday(&time, NULL);
2619 rb_entry_hdr.timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
2620
2621 /* Write if verbose and handler is set */
2622 if (info->rb_infos[DRIVER_PRINTS_RB_ID].verbose_level >= 1 &&
2623 info->on_ring_buffer_data) {
2624 /* Write header and payload separately to avoid
2625 * complete payload memcpy */
2626 status = ring_buffer_write(&info->rb_infos[DRIVER_PRINTS_RB_ID],
2627 (u8*)&rb_entry_hdr,
2628 sizeof(wifi_ring_buffer_entry),
2629 0,
2630 sizeof(wifi_ring_buffer_entry) + length);
2631 if (status != WIFI_SUCCESS) {
2632 ALOGE("Failed to write driver prints rb header %d", status);
2633 return status;
2634 }
2635 status = ring_buffer_write(&info->rb_infos[DRIVER_PRINTS_RB_ID],
2636 buf, length, 1, length);
2637 if (status != WIFI_SUCCESS) {
2638 ALOGE("Failed to write driver prints rb payload %d", status);
2639 return status;
2640 }
2641 }
2642
2643 return WIFI_SUCCESS;
2644 }
2645
diag_message_handler(hal_info * info,nl_msg * msg)2646 wifi_error diag_message_handler(hal_info *info, nl_msg *msg)
2647 {
2648 tAniNlHdr *wnl;
2649 u8 *buf;
2650 wifi_error status;
2651 tAniCLDHdr *clh = NULL;
2652 int cmd = 0;
2653
2654 if (info->cldctx) {
2655 struct nlattr *attrs[CLD80211_ATTR_MAX + 1];
2656 struct genlmsghdr *genlh;
2657 struct nlattr *tb_vendor[CLD80211_ATTR_MAX + 1];
2658 struct nlmsghdr *nlh = nlmsg_hdr(msg);
2659
2660 genlh = (struct genlmsghdr *)nlmsg_data(nlh);
2661 if (genlh->cmd == ANI_NL_MSG_PUMAC ||
2662 genlh->cmd == ANI_NL_MSG_LOG ||
2663 genlh->cmd == ANI_NL_MSG_CNSS_DIAG ||
2664 genlh->cmd == WLAN_NL_MSG_OEM)
2665 {
2666 cmd = genlh->cmd;
2667 int result = nla_parse(attrs, CLD80211_ATTR_MAX, genlmsg_attrdata(genlh, 0),
2668 genlmsg_attrlen(genlh, 0), NULL);
2669
2670 if (!result && attrs[CLD80211_ATTR_VENDOR_DATA]) {
2671 nla_parse(tb_vendor, CLD80211_ATTR_MAX,
2672 (struct nlattr *)nla_data(attrs[CLD80211_ATTR_VENDOR_DATA]),
2673 nla_len(attrs[CLD80211_ATTR_VENDOR_DATA]), NULL);
2674
2675 if (tb_vendor[CLD80211_ATTR_DATA]) {
2676 clh = (tAniCLDHdr *)nla_data(tb_vendor[CLD80211_ATTR_DATA]);
2677 }
2678 }
2679 if((info->wifihal_ctrl_sock.s > 0) && (genlh->cmd == WLAN_NL_MSG_OEM)) {
2680 wifihal_ctrl_event_t *ctrl_evt;
2681 wifihal_mon_sock_t *reg;
2682
2683 if (!(tb_vendor[CLD80211_ATTR_DATA] || tb_vendor[CLD80211_ATTR_CMD])) {
2684 ALOGE("Invalid oem data received from driver");
2685 return WIFI_ERROR_UNKNOWN;
2686 }
2687 ctrl_evt = (wifihal_ctrl_event_t *)malloc(sizeof(*ctrl_evt) + nlh->nlmsg_len);
2688
2689 if(ctrl_evt == NULL)
2690 {
2691 ALOGE("Memory allocation failure");
2692 return WIFI_ERROR_OUT_OF_MEMORY;
2693 }
2694 memset((char *)ctrl_evt, 0, sizeof(*ctrl_evt) + nlh->nlmsg_len);
2695
2696 ctrl_evt->family_name = CLD80211_FAMILY;
2697 ctrl_evt->cmd_id = WLAN_NL_MSG_OEM;
2698 ctrl_evt->data_len = nlh->nlmsg_len;
2699 memcpy(ctrl_evt->data, (char *)nlh, ctrl_evt->data_len);
2700
2701 //! Send oem data to all the registered clients
2702
2703 list_for_each_entry(reg, &info->monitor_sockets, list) {
2704
2705 if(reg == NULL)
2706 break;
2707
2708 if (reg->family_name != CLD80211_FAMILY || reg->cmd_id != WLAN_NL_MSG_OEM)
2709 continue;
2710
2711 /* found match! */
2712 /* Indicate the received OEM msg to respective client
2713 it is responsibility of the registered client to check
2714 the oem_msg is meant for them or not based on oem_msg sub type */
2715 if (sendto(info->wifihal_ctrl_sock.s, (char *)ctrl_evt,
2716 sizeof(*ctrl_evt) + ctrl_evt->data_len, 0,
2717 (struct sockaddr *)®->monsock, reg->monsock_len) < 0)
2718 {
2719 int _errno = errno;
2720 ALOGE("socket send failed : %d",_errno);
2721
2722 if (_errno == ENOBUFS || _errno == EAGAIN) {
2723 /*
2724 * The socket send buffer could be full. This
2725 * may happen if client programs are not
2726 * receiving their pending messages. Close and
2727 * reopen the socket as a workaround to avoid
2728 * getting stuck being unable to send any new
2729 * responses.
2730 */
2731 }
2732 }
2733 }
2734 free(ctrl_evt);
2735 return WIFI_SUCCESS;
2736 }
2737 }
2738 } else {
2739 wnl = (tAniNlHdr *)nlmsg_hdr(msg);
2740 cmd = wnl->nlh.nlmsg_type;
2741 }
2742
2743 if (!clh) {
2744 ALOGE("Invalid data received from driver");
2745 return WIFI_ERROR_UNKNOWN;
2746 }
2747 /* Check nlmsg_type also to avoid processing unintended msgs */
2748 if (cmd == ANI_NL_MSG_PUMAC) {
2749 if (!info->cldctx) {
2750 if ((wnl->nlh.nlmsg_len <= sizeof(tAniNlHdr)) ||
2751 (wnl->nlh.nlmsg_len < (sizeof(tAniNlHdr) + ntohs(wnl->clh.wmsg.length)))) {
2752 ALOGE("Received UMAC message with insufficent length: %d",
2753 wnl->nlh.nlmsg_len);
2754 return WIFI_ERROR_UNKNOWN;
2755 }
2756 clh = &wnl->clh;
2757 }
2758 if (clh->wmsg.type == ANI_NL_MSG_LOG_HOST_EVENT_LOG_TYPE) {
2759 uint32_t diag_host_type;
2760
2761 buf = (uint8_t *)(clh + 1);
2762 diag_host_type = *(uint32_t *)(buf);
2763 #ifdef QC_HAL_DEBUG
2764 ALOGV("diag type = %d", diag_host_type);
2765 #endif
2766 buf += sizeof(uint32_t); //diag_type
2767 if (diag_host_type == DIAG_TYPE_HOST_EVENTS) {
2768 host_event_hdr_t *event_hdr =
2769 (host_event_hdr_t *)(buf);
2770 #ifdef QC_HAL_DEBUG
2771 ALOGV("diag event_id = %x length %d",
2772 event_hdr->event_id, event_hdr->length);
2773 #endif
2774 buf += sizeof(host_event_hdr_t);
2775 switch (event_hdr->event_id) {
2776 case EVENT_WLAN_WAKE_LOCK:
2777 process_wakelock_event(info, buf, event_hdr->length);
2778 break;
2779 case EVENT_WLAN_PE:
2780 process_wlan_pe_event(info, buf, event_hdr->length);
2781 break;
2782 case EVENT_WLAN_EAPOL:
2783 process_wlan_eapol_event(info, buf, event_hdr->length);
2784 break;
2785 case EVENT_WLAN_LOG_COMPLETE:
2786 process_wlan_log_complete_event(info, buf, event_hdr->length);
2787 break;
2788 case EVENT_WLAN_LOW_RESOURCE_FAILURE:
2789 process_wlan_low_resource_failure(info, buf, event_hdr->length);
2790 break;
2791 case EVENT_WLAN_STA_DATA_STALL:
2792 process_wlan_data_stall_event(info, buf, event_hdr->length);
2793 break;
2794 default:
2795 return WIFI_SUCCESS;
2796 }
2797 } else if (diag_host_type == DIAG_TYPE_HOST_LOG_MSGS) {
2798 drv_msg_t *drv_msg = (drv_msg_t *) (buf);
2799 #ifdef QC_HAL_DEBUG
2800 ALOGV("diag event_type = %0x length = %d",
2801 drv_msg->event_type, drv_msg->length);
2802 #endif
2803 if (drv_msg->event_type == WLAN_PKT_LOG_STATS) {
2804 if ((info->prev_seq_no + 1) !=
2805 drv_msg->u.pkt_stats_event.msg_seq_no) {
2806 ALOGE("Few pkt stats messages missed: rcvd = %d, prev = %d",
2807 drv_msg->u.pkt_stats_event.msg_seq_no,
2808 info->prev_seq_no);
2809 if (info->pkt_stats->tx_stats_events) {
2810 info->pkt_stats->tx_stats_events = 0;
2811 memset(&info->pkt_stats->tx_stats, 0,
2812 sizeof(wifi_ring_per_packet_status_entry));
2813 }
2814 }
2815
2816 info->prev_seq_no =
2817 drv_msg->u.pkt_stats_event.msg_seq_no;
2818 status = parse_stats(info,
2819 drv_msg->u.pkt_stats_event.payload,
2820 drv_msg->u.pkt_stats_event.payload_len);
2821 if (status != WIFI_SUCCESS) {
2822 ALOGE("%s: Failed to parse Tx-Rx stats", __FUNCTION__);
2823 ALOGE("Received msg Seq_num : %d",
2824 drv_msg->u.pkt_stats_event.msg_seq_no);
2825 hexdump((char *)drv_msg->u.pkt_stats_event.payload,
2826 drv_msg->u.pkt_stats_event.payload_len);
2827 return status;
2828 }
2829 }
2830 }
2831 }
2832 } else if (cmd == ANI_NL_MSG_LOG) {
2833 if (!info->cldctx) {
2834 if ((wnl->nlh.nlmsg_len <= sizeof(tAniNlHdr)) ||
2835 (wnl->nlh.nlmsg_len < (sizeof(tAniNlHdr) + wnl->clh.wmsg.length))) {
2836 ALOGE("Received LOG message with insufficent length: %d",
2837 wnl->nlh.nlmsg_len);
2838 return WIFI_ERROR_UNKNOWN;
2839 }
2840 clh = &wnl->clh;
2841 }
2842 if (clh->wmsg.type == ANI_NL_MSG_LOG_HOST_PRINT_TYPE) {
2843 process_driver_prints(info, (u8 *)(clh + 1), clh->wmsg.length);
2844 } else if (clh->wmsg.type == ANI_NL_MSG_LOG_FW_MSG_TYPE) {
2845 process_firmware_prints(info, (u8 *)(clh + 1), clh->wmsg.length);
2846 }
2847 } else if (cmd == ANI_NL_MSG_CNSS_DIAG) {
2848 uint16_t diag_fw_type;
2849 struct nlmsghdr *nlh = nlmsg_hdr(msg);
2850
2851 if (!info->cldctx) {
2852 buf = (uint8_t *)NLMSG_DATA(wnl) + sizeof(wnl->clh.radio);
2853 } else {
2854 buf = (uint8_t *)&clh->wmsg;
2855 }
2856
2857 fw_event_hdr_t *event_hdr =
2858 (fw_event_hdr_t *)(buf);
2859 if (!info->cldctx) {
2860 if ((wnl->nlh.nlmsg_len <= NLMSG_HDRLEN + sizeof(fw_event_hdr_t)) ||
2861 (wnl->nlh.nlmsg_len < (NLMSG_HDRLEN + sizeof(fw_event_hdr_t) +
2862 event_hdr->length))) {
2863 ALOGE("Received CNSS_DIAG message with insufficent length: %d",
2864 wnl->nlh.nlmsg_len);
2865 return WIFI_ERROR_UNKNOWN;
2866 }
2867 } else {
2868 if (nlh->nlmsg_len <= NLMSG_HDRLEN + sizeof(dbglog_slot)) {
2869 ALOGE("Received CNSS_DIAG message with insufficent length: %d: %s:%d",
2870 nlh->nlmsg_len, __FUNCTION__, __LINE__);
2871 return WIFI_ERROR_UNKNOWN;
2872 }
2873 }
2874 diag_fw_type = event_hdr->diag_type;
2875 if (diag_fw_type == DIAG_TYPE_FW_MSG) {
2876 dbglog_slot *slot;
2877 u16 length = 0;
2878
2879 slot = (dbglog_slot *)buf;
2880 if (nlh->nlmsg_len < (NLMSG_HDRLEN + sizeof(dbglog_slot) +
2881 slot->length)) {
2882 ALOGE("Received CNSS_DIAG message with insufficent length: %d:"
2883 " expected: %zu, %s:%d",
2884 nlh->nlmsg_len,
2885 (NLMSG_HDRLEN + sizeof(dbglog_slot) +slot->length),
2886 __FUNCTION__,
2887 __LINE__);
2888 return WIFI_ERROR_UNKNOWN;
2889 }
2890 length = get_le32((u8 *)&slot->length);
2891 process_fw_diag_msg(info, &slot->payload[0], length);
2892 }
2893 }
2894 return WIFI_SUCCESS;
2895 }
2896