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