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