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