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