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