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