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