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