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