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