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