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