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