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