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