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