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 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 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 223static 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 277static 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 397static 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 539static 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 583static 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 627static 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 770wifi_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 807static 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 846static 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 1033static 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 1046static 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 1096static 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 1149static 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 1221static 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 1239static 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 1282static 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 1310static 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 1379static 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 1416static 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 1540static 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 1578static 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 1632static 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 1648static 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 1826wifi_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 1865static 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 1905static 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 1945static 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 1967static 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 1974static 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 2002static 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 2042static 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 2077wifi_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 2114wifi_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