diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-08-25 08:30:40 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2022-08-25 08:30:40 +0000 |
commit | 28a37192378c189700e3908ab766fe3a1abfa03b (patch) | |
tree | 227fe25d51cb66243ff14f1521f1e5d56cbcc226 | |
parent | 914dea9c7e2c636500ae5b8009a63074bd8ebb9a (diff) | |
parent | cac2b64e2426a1f161e2fd22f762c3df6c70ce6a (diff) | |
download | wlan-gki13-boot-release.tar.gz |
Merge "Snap for 8992082 from 5b819ee4ec00564efbf3ce69924933c515977a65 to gki13-boot-release" into gki13-boot-releasegki13-boot-release
-rw-r--r-- | OWNERS | 3 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/Android.bp | 90 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/Android.mk | 67 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/common.cpp | 2 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/common.h | 51 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/cpp_bindings.cpp | 47 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/cpp_bindings.h | 2 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/gscan.cpp | 2 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/link_layer_stats.cpp | 176 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/nan.cpp | 435 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/rtt.cpp | 2 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/twt.cpp | 2 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/wifi_hal.cpp | 127 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/wifi_logger.cpp | 831 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/wifi_offload.cpp | 2 |
15 files changed, 1658 insertions, 181 deletions
@@ -0,0 +1,3 @@ +arabawy@google.com +etancohen@google.com +kumachang@google.com diff --git a/bcmdhd/wifi_hal/Android.bp b/bcmdhd/wifi_hal/Android.bp new file mode 100644 index 0000000..92498f3 --- /dev/null +++ b/bcmdhd/wifi_hal/Android.bp @@ -0,0 +1,90 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Make the HAL library +// ============================================================ +package { + // See: http://go/android-license-faq + default_applicable_licenses: [ + "Android-Apache-2.0", + ], +} + +soong_config_module_type_import { + from: "frameworks/opt/net/wifi/libwifi_hal/Android.bp", + module_types: ["wifi_cc_defaults"], +} + +wifi_cc_defaults { + name: "libwifi-hal-bcm-defaults", + soong_config_variables: { + google_wifi_config_lib: { + shared_libs: ["google_wifi_firmware_config_version_c_wrapper"], + cflags: [ + "-DGOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER", + // only for pixel feature + "-DRING_DUMP", + ], + }, + }, +} + +cc_library_static { + name: "libwifi-hal-bcm", + + cflags: [ + "-Wall", + "-Werror", + "-Wno-format", + "-Wno-reorder", + "-Wno-unused-function", + "-Wno-unused-parameter", + "-Wno-unused-private-field", + "-Wno-unused-variable", + "-Wno-unused-parameter", + ], + + defaults: [ + "libwifi-hal-bcm-defaults", + ], + + header_libs: [ + "libnetlink_iface_headers", + "libhardware_legacy_headers", + ], + + shared_libs: [ + // added for libwifi-hal-bcm + "libcrypto", + // shared_libs in libwifi-hal + "liblog", + "libnl", + "libutils", + ], + + srcs: [ + "wifi_hal.cpp", + "rtt.cpp", + "common.cpp", + "cpp_bindings.cpp", + "gscan.cpp", + "nan.cpp", + "link_layer_stats.cpp", + "wifi_logger.cpp", + "wifi_offload.cpp", + "twt.cpp", + ], + + proprietary: true, +} diff --git a/bcmdhd/wifi_hal/Android.mk b/bcmdhd/wifi_hal/Android.mk deleted file mode 100755 index 580a730..0000000 --- a/bcmdhd/wifi_hal/Android.mk +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (C) 2011 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH := $(call my-dir) - -# Make the HAL library -# ============================================================ -include $(CLEAR_VARS) - -LOCAL_CFLAGS := \ - -Wall \ - -Werror \ - -Wno-format \ - -Wno-reorder \ - -Wno-unused-function \ - -Wno-unused-parameter \ - -Wno-unused-private-field \ - -Wno-unused-variable \ - -Wno-unused-parameter - -LOCAL_C_INCLUDES += \ - external/libnl/include \ - $(call include-path-for, libhardware_legacy)/hardware_legacy \ - external/wpa_supplicant_8/src/drivers - -LOCAL_C_INCLUDES += \ - external/boringssl/include \ - external/boringssl/src/crypto/digest \ - external/boringssl/src/crypto/evp/ - -LOCAL_HEADER_LIBRARIES := libutils_headers liblog_headers - -ifneq ($(wildcard vendor/google/libraries/GoogleWifiConfigLib),) -LOCAL_SHARED_LIBRARIES += \ - google_wifi_firmware_config_version_c_wrapper -LOCAL_CFLAGS += -DGOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER -endif - -LOCAL_SRC_FILES := \ - wifi_hal.cpp \ - rtt.cpp \ - common.cpp \ - cpp_bindings.cpp \ - gscan.cpp \ - nan.cpp \ - link_layer_stats.cpp \ - wifi_logger.cpp \ - wifi_offload.cpp \ - twt.cpp - -LOCAL_MODULE := libwifi-hal-bcm -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_PROPRIETARY_MODULE := true - -include $(BUILD_STATIC_LIBRARY) diff --git a/bcmdhd/wifi_hal/common.cpp b/bcmdhd/wifi_hal/common.cpp index 5a9d5ab..1a55aac 100755 --- a/bcmdhd/wifi_hal/common.cpp +++ b/bcmdhd/wifi_hal/common.cpp @@ -33,7 +33,7 @@ #include <netlink/socket.h> #include <netlink/handlers.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "cpp_bindings.h" diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h index 9065802..e9df748 100755 --- a/bcmdhd/wifi_hal/common.h +++ b/bcmdhd/wifi_hal/common.h @@ -16,7 +16,7 @@ * limitations under the License. */ -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #ifndef __WIFI_HAL_COMMON_H__ #define __WIFI_HAL_COMMON_H__ @@ -54,8 +54,11 @@ const uint32_t BRCM_OUI = 0x001018; #define NMR2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7] #define NMRSTR "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" #define NAN_MASTER_RANK_LEN 8 +#define NAN_SCID_INFO_LEN 16 #define SAR_CONFIG_SCENARIO_COUNT 100 +#define MAX_NUM_RADIOS 3 +#define MAX_CMD_RESP_BUF_LEN 8192 /* This enum defines ranges for various commands; commands themselves @@ -229,7 +232,7 @@ typedef enum { WIFI_SUBCMD_OTA_UPDATE, WIFI_SUBCMD_USABLE_CHANNEL = ANDROID_NL80211_SUBCMD_USABLE_CHANNEL_START, WIFI_SUBCMD_TRIGGER_SSR = ANDROID_NL80211_SUBCMD_INIT_DEINIT_RANGE_START, - + WIFI_SUBCMD_GET_RADIO_COMBO_MATRIX, } WIFI_SUB_COMMAND; typedef enum { @@ -303,6 +306,12 @@ typedef struct { bool is_virtual; // mark each iface as virtual or static } interface_info; +typedef enum { + NAN_STATE_DISABLED = 0, + NAN_STATE_AP = 1, + NAN_STATE_CHRE = 2, +} nan_enab_state_t; + typedef struct { struct nl_sock *cmd_sock; // command socket object @@ -330,6 +339,8 @@ typedef struct { int max_num_interfaces; // max number of interfaces wifi_subsystem_restart_handler restart_handler; // trigger sub system handler + wifi_chre_handler chre_nan_cb; // chre CB for nan status + nan_enab_state_t nan_state; // Nan enable state // add other details } hal_info; @@ -445,6 +456,12 @@ wifi_error wifi_start_hal(wifi_interface_handle iface); wifi_error wifi_stop_hal(wifi_interface_handle iface); wifi_interface_handle wifi_get_wlan_interface(wifi_handle info, wifi_interface_handle *ifaceHandles, int numIfaceHandles); +#ifdef RING_DUMP +wifi_error wifi_start_ring_dump(wifi_interface_handle iface, + wifi_ring_buffer_data_handler ring_handle); +wifi_error wifi_stop_ring_dump(wifi_interface_handle iface, + wifi_ring_buffer_data_handler ring_handle); +#endif /* RING_DUMP */ wifi_error wifi_hal_ota_update(wifi_interface_handle iface, uint32_t ota_version); wifi_error wifi_hal_preInit(wifi_interface_handle iface); /* API to get wake reason statistics */ @@ -524,6 +541,36 @@ wifi_error twt_get_stats(wifi_interface_handle iface, u8 config_id, TwtStats* st wifi_error twt_clear_stats(wifi_interface_handle iface, u8 config_id); wifi_error wifi_trigger_subsystem_restart(wifi_handle handle); + +/**@brief nan_chre_enable_request + * Request from CHRE to enable NAN + * @param transaction id: + * @param wifi_interface_handle: + * @param NanEnableRequest: + * @return Synchronous wifi_error + */ +wifi_error nan_chre_enable_request(transaction_id id, + wifi_interface_handle iface, + NanEnableRequest* msg); + +/**@brief nan_chre_disable_request + * Request from CHRE to disable NAN + * @param transaction id: + * @param wifi_interface_handle: + * @return Synchronous wifi_error + */ +wifi_error nan_chre_disable_request(transaction_id id, + wifi_interface_handle iface); + +/**@brief nan_chre_register_handler + * Register chre handler to handle NAN status + * @param wifi_interface_handle: + * @param wifi_chre_handler: + * @return Synchronous wifi_error + */ +wifi_error nan_chre_register_handler(wifi_interface_handle iface, + wifi_chre_handler handler); + // some common macros #define min(x, y) ((x) < (y) ? (x) : (y)) diff --git a/bcmdhd/wifi_hal/cpp_bindings.cpp b/bcmdhd/wifi_hal/cpp_bindings.cpp index 698789d..310918c 100755 --- a/bcmdhd/wifi_hal/cpp_bindings.cpp +++ b/bcmdhd/wifi_hal/cpp_bindings.cpp @@ -36,7 +36,7 @@ #include <ctype.h> #include <errno.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "cpp_bindings.h" @@ -579,27 +579,56 @@ int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) { } } +static int mapErrorCodes(int err) +{ + int ret; + if (!err) { + return WIFI_SUCCESS; + } + switch (err) { + case -EOPNOTSUPP: + ret = WIFI_ERROR_NOT_SUPPORTED; + break; + case -ETIMEDOUT: + ret = WIFI_ERROR_TIMED_OUT; + break; + case -EINVAL: + ret = WIFI_ERROR_INVALID_ARGS; + break; + case -ENOMEM: + ret = WIFI_ERROR_OUT_OF_MEMORY; + break; + case -EBUSY: + ret = WIFI_ERROR_BUSY; + break; + default: + ret = WIFI_ERROR_UNKNOWN; + } + ALOGD("error code %d mapped to %d", err, ret); + return ret; +} + int WifiRequest::create(uint32_t id, int subcmd) { int res = create(NL80211_CMD_VENDOR); if (res < 0) { - return res; + return mapErrorCodes(res); } res = put_u32(NL80211_ATTR_VENDOR_ID, id); if (res < 0) { - return res; + return mapErrorCodes(res); } res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd); if (res < 0) { - return res; + return mapErrorCodes(res); } if (mIface != -1) { res = set_iface_id(mIface); } - return res; + return mapErrorCodes(res); } @@ -618,7 +647,6 @@ int WifiCommand::requestResponse() { } int WifiCommand::requestResponse(WifiRequest& request) { - pthread_mutex_lock(&ResponseMutex); int err = 0; struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); @@ -645,8 +673,7 @@ int WifiCommand::requestResponse(WifiRequest& request) { } out: nl_cb_put(cb); - pthread_mutex_unlock(&ResponseMutex); - return err; + return mapErrorCodes(err); } int WifiCommand::requestEvent(int cmd) { @@ -675,7 +702,7 @@ int WifiCommand::requestEvent(int cmd) { out: wifi_unregister_handler(wifiHandle(), cmd); - return res; + return mapErrorCodes(res); } int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) { @@ -699,7 +726,7 @@ int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) { out: wifi_unregister_vendor_handler(wifiHandle(), id, subcmd); - return res; + return mapErrorCodes(res); } /* Event handlers */ diff --git a/bcmdhd/wifi_hal/cpp_bindings.h b/bcmdhd/wifi_hal/cpp_bindings.h index 8b5600a..cc1c662 100755 --- a/bcmdhd/wifi_hal/cpp_bindings.h +++ b/bcmdhd/wifi_hal/cpp_bindings.h @@ -16,7 +16,7 @@ * limitations under the License. */ -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "sync.h" diff --git a/bcmdhd/wifi_hal/gscan.cpp b/bcmdhd/wifi_hal/gscan.cpp index 995c989..19bab2b 100755 --- a/bcmdhd/wifi_hal/gscan.cpp +++ b/bcmdhd/wifi_hal/gscan.cpp @@ -40,7 +40,7 @@ #include <log/log.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "cpp_bindings.h" diff --git a/bcmdhd/wifi_hal/link_layer_stats.cpp b/bcmdhd/wifi_hal/link_layer_stats.cpp index a2aabe3..850b8fd 100644 --- a/bcmdhd/wifi_hal/link_layer_stats.cpp +++ b/bcmdhd/wifi_hal/link_layer_stats.cpp @@ -39,10 +39,17 @@ #include <utils/Log.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "cpp_bindings.h" +typedef enum { + ANDR_WIFI_ATTRIBUTE_INVALID = 0, + ANDR_WIFI_ATTRIBUTE_NUM_RADIO = 1, + ANDR_WIFI_ATTRIBUTE_STATS_INFO = 2, + ANDR_WIFI_ATTRIBUTE_STATS_MAX = 3 +} LINK_STAT_ATTRIBUTE; + /* Internal radio statistics structure in the driver */ typedef struct { wifi_radio radio; @@ -85,6 +92,12 @@ public: protected: virtual int handleResponse(WifiEvent& reply) { + void *data = NULL; + wifi_radio_stat *radio_stat_ptr = NULL; + u8 *iface_stat = NULL; + u8 *radioStatsBuf = NULL, *output = NULL, *data_ptr = NULL; + uint32_t total_size = 0, per_radio_size = 0, data_len = 0, rem_len = 0; + int num_radios = 0, id = 0, subcmd = 0, len = 0; // ALOGI("In GetLinkStatsCommand::handleResponse"); @@ -93,34 +106,153 @@ protected: return NL_SKIP; } - int id = reply.get_vendor_id(); - - void *data = reply.get_vendor_data(); - int len = reply.get_vendor_data_len(); - if (!data || !len) { - ALOGE("Invalid vendor data received"); - return NL_SKIP; - } - wifi_radio_stat *radio_stat = - convertToExternalRadioStatStructure((wifi_radio_stat_internal *)data); - if (!radio_stat) { - ALOGE("Invalid stats pointer received"); + id = reply.get_vendor_id(); + subcmd = reply.get_vendor_subcmd(); + nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); + len = reply.get_vendor_data_len(); + + ALOGV("Id = %0x, subcmd = %d, len = %d\n", id, subcmd, len); + if (vendor_data == NULL || len == 0) { + ALOGE("no vendor data in GetLinkStatCommand response; ignoring it"); return NL_SKIP; } - wifi_iface_stat *iface_stat = - (wifi_iface_stat *)((char *)&((wifi_radio_stat_internal *)data)->channels - + radio_stat->num_channels * sizeof(wifi_channel_stat)); - (*mHandler.on_link_stats_results)(id, iface_stat, 1, radio_stat); - free(radio_stat); + + for (nl_iterator it(vendor_data); it.has_next(); it.next()) { + if (it.get_type() == ANDR_WIFI_ATTRIBUTE_NUM_RADIO) { + num_radios = it.get_u32(); + } else if (it.get_type() == ANDR_WIFI_ATTRIBUTE_STATS_INFO) { + data = it.get_data(); + data_len = it.get_len(); + } else { + ALOGW("Ignoring invalid attribute type = %d, size = %d\n", + it.get_type(), it.get_len()); + } + } + + if (num_radios) { + rem_len = MAX_CMD_RESP_BUF_LEN; + radioStatsBuf = (u8 *)malloc(MAX_CMD_RESP_BUF_LEN); + if (!radioStatsBuf) { + ALOGE("No memory\n"); + return NL_SKIP; + } + memset(radioStatsBuf, 0, MAX_CMD_RESP_BUF_LEN); + output = radioStatsBuf; + + if (!data || !data_len) { + ALOGE("%s: null data\n", __func__); + return NL_SKIP; + } + + data_ptr = (u8*)data; + for (int i = 0; i < num_radios; i++) { + rem_len -= per_radio_size; + if (rem_len < per_radio_size) { + ALOGE("No data left for radio %d\n", i); + goto exit; + } + data_ptr = (u8*)data + total_size; + if (!data_ptr) { + ALOGE("Invalid data for radio index = %d\n", i); + goto exit; + } + radio_stat_ptr = + convertToExternalRadioStatStructure((wifi_radio_stat*)data_ptr, + &per_radio_size); + if (!radio_stat_ptr || !per_radio_size) { + ALOGE("No data for radio %d\n", i); + continue; + } + memcpy(output, radio_stat_ptr, per_radio_size); + output += per_radio_size; + total_size += per_radio_size; + } + + iface_stat = ((u8*)data + total_size); + if (!iface_stat || data_len < total_size) { + ALOGE("No data for iface stats!!, data_len = %d, total_size = %d\n", + data_len, total_size); + goto exit; + } + (*mHandler.on_link_stats_results)(id, (wifi_iface_stat *)iface_stat, + num_radios, (wifi_radio_stat *)radioStatsBuf); + } else { + /* To be deprecated, adding it to keep it backward compatible */ + ALOGD("GetLinkStatCommand: zero radio case\n"); + data = reply.get_vendor_data(); + if (!data) { + ALOGE("Invalid vendor data received\n"); + return NL_SKIP; + } + + num_radios = 1; + data = reply.get_vendor_data(); + len = reply.get_vendor_data_len(); + if (!data || !len) { + ALOGE("Invalid vendor data received\n"); + return NL_SKIP; + } + radio_stat_ptr = + convertToExternalRadioStatStructureLegacy((wifi_radio_stat_internal *)data); + if (!radio_stat_ptr) { + ALOGE("Invalid stats pointer received\n"); + return NL_SKIP; + } + wifi_iface_stat *iface_stat = + (wifi_iface_stat *)((char *)&((wifi_radio_stat_internal *)data)->channels + + radio_stat_ptr->num_channels * sizeof(wifi_channel_stat)); + (*mHandler.on_link_stats_results)(id, iface_stat, num_radios, radio_stat_ptr); + } +exit: + if (radio_stat_ptr) { + free(radio_stat_ptr); + radio_stat_ptr = NULL; + } + if (radioStatsBuf) { + free(radioStatsBuf); + radioStatsBuf = NULL; + } return NL_OK; } private: - wifi_radio_stat *convertToExternalRadioStatStructure(wifi_radio_stat_internal *internal_stat_ptr) { + wifi_radio_stat *convertToExternalRadioStatStructure(wifi_radio_stat *internal_stat_ptr, + uint32_t *per_radio_size) { + wifi_radio_stat *external_stat_ptr = NULL; + if (!internal_stat_ptr) { + ALOGE("Incoming data is null\n"); + } else { + uint32_t channel_size = internal_stat_ptr->num_channels * sizeof(wifi_channel_stat); + *per_radio_size = offsetof(wifi_radio_stat, channels) + channel_size; + external_stat_ptr = (wifi_radio_stat *)malloc(*per_radio_size); + if (external_stat_ptr) { + external_stat_ptr->radio = internal_stat_ptr->radio; + external_stat_ptr->on_time = internal_stat_ptr->on_time; + external_stat_ptr->tx_time = internal_stat_ptr->tx_time; + external_stat_ptr->num_tx_levels = internal_stat_ptr->num_tx_levels; + external_stat_ptr->tx_time_per_levels = NULL; + external_stat_ptr->rx_time = internal_stat_ptr->rx_time; + external_stat_ptr->on_time_scan = internal_stat_ptr->on_time_scan; + external_stat_ptr->on_time_nbd = internal_stat_ptr->on_time_nbd; + external_stat_ptr->on_time_gscan = internal_stat_ptr->on_time_gscan; + external_stat_ptr->on_time_roam_scan = internal_stat_ptr->on_time_roam_scan; + external_stat_ptr->on_time_pno_scan = internal_stat_ptr->on_time_pno_scan; + external_stat_ptr->on_time_hs20 = internal_stat_ptr->on_time_hs20; + external_stat_ptr->num_channels = internal_stat_ptr->num_channels; + if (internal_stat_ptr->num_channels) { + memcpy(&(external_stat_ptr->channels), &(internal_stat_ptr->channels), + channel_size); + } + } + } + return external_stat_ptr; + } + + wifi_radio_stat *convertToExternalRadioStatStructureLegacy(wifi_radio_stat_internal *internal_stat_ptr) { wifi_radio_stat *external_stat_ptr = NULL; - if (!internal_stat_ptr) { - ALOGE("Sta_ptr is null\n"); - } else { + if (!internal_stat_ptr) { + ALOGE("Sta_ptr is null\n"); + } else { uint32_t channel_size = internal_stat_ptr->num_channels * sizeof(wifi_channel_stat); uint32_t total_size = sizeof(wifi_radio_stat) + channel_size; external_stat_ptr = (wifi_radio_stat *)malloc(total_size); diff --git a/bcmdhd/wifi_hal/nan.cpp b/bcmdhd/wifi_hal/nan.cpp index 0805128..e74d9a1 100755 --- a/bcmdhd/wifi_hal/nan.cpp +++ b/bcmdhd/wifi_hal/nan.cpp @@ -40,13 +40,13 @@ #include <utils/Log.h> #include <log/log.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "cpp_bindings.h" #include "netinet/in.h" #include "arpa/inet.h" #include <openssl/sha.h> -#include <openssl/evp.h> +#include <openssl/evp.h> #include <sys/ioctl.h> /* Changes between incompatible Version of NAN */ @@ -288,7 +288,10 @@ typedef enum { NAN_ATTRIBUTE_ENABLE_RANGING = 226, NAN_ATTRIBUTE_DW_EARLY_TERM = 227, NAN_ATTRIBUTE_CHANNEL_INFO = 228, - NAN_ATTRIBUTE_NUM_CHANNELS = 229 + NAN_ATTRIBUTE_NUM_CHANNELS = 229, + NAN_ATTRIBUTE_INSTANT_MODE_ENABLE = 230, + NAN_ATTRIBUTE_INSTANT_COMM_CHAN = 231, + NAN_ATTRIBUTE_CHRE_REQUEST = 232, } NAN_ATTRIBUTE; typedef enum { @@ -857,6 +860,11 @@ class NanDiscEnginePrimitive : public WifiCommand } if (mParams->scid_len) { + if ((mParams->scid_len > NAN_MAX_SCID_BUF_LEN) || + (mParams->scid_len % NAN_SCID_INFO_LEN)) { + ALOGE("%s: Invalid scid len, = %d\n", __func__, mParams->scid_len); + return NAN_STATUS_INVALID_PARAM; + } result = request.put_u32(NAN_ATTRIBUTE_SCID_LEN, mParams->scid_len); if (result < 0) { @@ -1168,7 +1176,45 @@ class NanDiscEnginePrimitive : public WifiCommand return result; } + result = request.put_u8(NAN_ATTRIBUTE_CIPHER_SUITE_TYPE, + mParams->cipher_type); + if (result < 0) { + ALOGE("%s: Failed to fill NAN_ATTRIBUTE_CIPHER_SUITE_TYPE, result = %d\n", + __func__, result); + return result; + } + + result = request.put_u8(NAN_ATTRIBUTE_KEY_TYPE, + mParams->key_info.key_type); + if (result < 0) { + ALOGE("%s: Failed to fill NAN_ATTRIBUTE_KEY_TYPE, result = %d\n", + __func__, result); + return result; + } + + if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) { + if (mParams->key_info.body.pmk_info.pmk_len) { + result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN, + mParams->key_info.body.pmk_info.pmk_len); + if (result < 0) { + ALOGE("%s: Failed to fill pmk len, result = %d\n", __func__, result); + return result; + } + result = request.put(NAN_ATTRIBUTE_KEY_DATA, + (void *)mParams->key_info.body.pmk_info.pmk, + mParams->key_info.body.pmk_info.pmk_len); + if (result < 0) { + ALOGE("%s: Failed to fill pmk, result = %d\n", __func__, result); + return result; + } + } + } + if (mParams->scid_len) { + if (mParams->scid_len != NAN_SCID_INFO_LEN) { + ALOGE("%s: Invalid scid len, = %d\n", __func__, mParams->scid_len); + return NAN_STATUS_INVALID_PARAM; + } result = request.put_u32(NAN_ATTRIBUTE_SCID_LEN, mParams->scid_len); if (result < 0) { @@ -1176,7 +1222,6 @@ class NanDiscEnginePrimitive : public WifiCommand return result; } - prhex(NULL, mParams->scid, mParams->scid_len); result = request.put(NAN_ATTRIBUTE_SCID, (void *)mParams->scid, mParams->scid_len); if (result < 0) { @@ -2014,6 +2059,26 @@ class NanDataPathPrimitive : public WifiCommand } } + if (mParams->scid_len) { + if (mParams->scid_len != NAN_SCID_INFO_LEN) { + ALOGE("%s: Invalid scid len, = %d\n", __func__, mParams->scid_len); + return NAN_STATUS_INVALID_PARAM; + } + result = request.put_u32(NAN_ATTRIBUTE_SCID_LEN, + mParams->scid_len); + if (result < 0) { + ALOGE("%s: Failed to fill scid len, result = %d\n", __func__, result); + return result; + } + + result = request.put(NAN_ATTRIBUTE_SCID, + (void *)mParams->scid, mParams->scid_len); + if (result < 0) { + ALOGE("%s: Failed to fill scid, result = %d\n", __func__, result); + return result; + } + } + request.attr_end(data); return WIFI_SUCCESS; } @@ -2159,6 +2224,27 @@ class NanDataPathPrimitive : public WifiCommand } } + if (mParams->scid_len) { + if (mParams->scid_len != NAN_SCID_INFO_LEN) { + ALOGE("%s: Invalid scid len, = %d\n", __func__, mParams->scid_len); + return NAN_STATUS_INVALID_PARAM; + } + result = request.put_u32(NAN_ATTRIBUTE_SCID_LEN, + mParams->scid_len); + if (result < 0) { + ALOGE("%s: Failed to fill scid len, result = %d\n", __func__, result); + return result; + } + + prhex(NULL, mParams->scid, mParams->scid_len); + result = request.put(NAN_ATTRIBUTE_SCID, + (void *)mParams->scid, mParams->scid_len); + if (result < 0) { + ALOGE("%s: Failed to fill scid, result = %d\n", __func__, result); + return result; + } + } + request.attr_end(data); return WIFI_SUCCESS; } @@ -2300,7 +2386,7 @@ class NanDataPathPrimitive : public WifiCommand attr_type = it.get_type(); if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) { - ALOGI("publish_id: %u", it.get_u32()); + ALOGI("publish_id: %u\n", it.get_u32()); ndp_request_event.service_instance_id = it.get_u32(); } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) { @@ -2310,17 +2396,17 @@ class NanDataPathPrimitive : public WifiCommand MAC2STR(ndp_request_event.peer_disc_mac_addr)); } else if (attr_type == NAN_ATTRIBUTE_NDP_ID) { - ALOGI("ndp id: %u", it.get_u32()); + ALOGI("ndp id: %u\n", it.get_u32()); ndp_request_event.ndp_instance_id = it.get_u32(); } else if (attr_type == NAN_ATTRIBUTE_SECURITY) { - ALOGI("security: %u", + ALOGI("security: %u\n", (NanDataPathSecurityCfgStatus)it.get_u8()); ndp_request_event.ndp_cfg.security_cfg = (NanDataPathSecurityCfgStatus)it.get_u8(); } else if (attr_type == NAN_ATTRIBUTE_QOS) { - ALOGI("QoS: %u", (NanDataPathQosCfg)it.get_u8()); + ALOGI("QoS: %u\n", (NanDataPathQosCfg)it.get_u8()); ndp_request_event.ndp_cfg.qos_cfg = (NanDataPathQosCfg)it.get_u8(); } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) { @@ -2332,7 +2418,17 @@ class NanDataPathPrimitive : public WifiCommand ndp_ind_app_info_len); ndp_request_event.app_info.ndp_app_info [ndp_ind_app_info_len] = '\0'; - ALOGI("service info: %s", ndp_request_event.app_info.ndp_app_info); + ALOGI("service info: %s\n", ndp_request_event.app_info.ndp_app_info); + + } else if (attr_type == NAN_ATTRIBUTE_SCID_LEN) { + ALOGI("scid len: %u\n", it.get_u32()); + ndp_request_event.scid_len = it.get_u32(); + + } else if (attr_type == NAN_ATTRIBUTE_SCID) { + memcpy(ndp_request_event.scid, it.get_data(), + ndp_request_event.scid_len); + ndp_request_event.scid[ndp_request_event.scid_len] = '\0'; + ALOGI("scid : %s\n", ndp_request_event.scid); } } @@ -2448,6 +2544,7 @@ class NanMacControl : public WifiCommand wifi_interface_handle mIface; NanRequestType mType; u32 mVersion; + u8 mChreNan; public: NanMacControl(wifi_interface_handle iface, int id, @@ -2487,6 +2584,10 @@ class NanMacControl : public WifiCommand mParams = params; } + void setChreNan(u8 chre_nan) { + mChreNan = chre_nan; + } + int createRequest(WifiRequest& request) { ALOGI("NAN CMD: %s\n", NanCmdToString(mType)); if (mType == NAN_REQUEST_ENABLE) { @@ -2866,6 +2967,32 @@ class NanMacControl : public WifiCommand } } + if (mParams->config_enable_instant_mode) { + result = request.put_u32(NAN_ATTRIBUTE_INSTANT_MODE_ENABLE, + mParams->enable_instant_mode); + if (result < 0) { + ALOGE("%s: Failing to fill enable instant mode, result = %d\n", __func__, result); + return result; + } + } + + if (mParams->enable_instant_mode && mParams->config_instant_mode_channel + && mParams->instant_mode_channel) { + result = request.put_u32(NAN_ATTRIBUTE_INSTANT_COMM_CHAN, + mParams->instant_mode_channel); + if (result < 0) { + ALOGE("%s: Failing in config instant channel, result = %d\n", __func__, result); + return result; + } + ALOGI("%s: instant mode channel = %d\n", __func__, mParams->instant_mode_channel); + } + + result = request.put_u8(NAN_ATTRIBUTE_CHRE_REQUEST, mChreNan); + if (result < 0) { + ALOGE("%s: Failing in config chreNan, result = %d\n", __func__, result); + return result; + } + request.attr_end(data); NAN_DBG_EXIT(); return WIFI_SUCCESS; @@ -2882,6 +3009,12 @@ class NanMacControl : public WifiCommand nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); + result = request.put_u8(NAN_ATTRIBUTE_CHRE_REQUEST, mChreNan); + if (result < 0) { + ALOGE("%s: Failing in config chreNan, result = %d\n", __func__, result); + return result; + } + request.attr_end(data); NAN_DBG_EXIT(); @@ -3129,6 +3262,27 @@ class NanMacControl : public WifiCommand return result; } } + + if (mParams->config_enable_instant_mode) { + result = request.put_u32(NAN_ATTRIBUTE_INSTANT_MODE_ENABLE, + mParams->enable_instant_mode); + if (result < 0) { + ALOGE("%s: Failing to fill enable instant mode, result = %d\n", __func__, result); + return result; + } + } + + if (mParams->enable_instant_mode && mParams->config_instant_mode_channel + && mParams->instant_mode_channel) { + result = request.put_u32(NAN_ATTRIBUTE_INSTANT_COMM_CHAN, + mParams->instant_mode_channel); + if (result < 0) { + ALOGE("%s: Failing in config instant channel, result = %d\n", __func__, result); + return result; + } + ALOGI("%s: instant mode channel = %d\n", __func__, mParams->instant_mode_channel); + } + request.attr_end(data); NAN_DBG_EXIT(); return WIFI_SUCCESS; @@ -3186,6 +3340,10 @@ class NanMacControl : public WifiCommand return NL_SKIP; } + if (mChreNan) { + return NL_SKIP; + } + rsp_vndr_data = (nan_hal_resp_t *)reply.get_vendor_data(); ALOGI("NanMacControl::handleResponse\n"); if (mType == NAN_VERSION_INFO) { @@ -3251,7 +3409,6 @@ class NanMacControl : public WifiCommand } int handleEvent(WifiEvent& event) { - u16 inst_id; u32 ndp_instance_id = 0; int event_id = event.get_vendor_subcmd(); nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); @@ -3266,11 +3423,14 @@ class NanMacControl : public WifiCommand return NL_SKIP; } + if (mChreNan) { + return NL_SKIP; + } + for (nl_iterator it(vendor_data); it.has_next(); it.next()) { attr_type = it.get_type(); if (it.get_type() == NAN_ATTRIBUTE_HANDLE) { - inst_id = it.get_u8(); } else if (it.get_type() == NAN_ATTRIBUTE_NDP_ID) { ndp_instance_id = it.get_u32(); ALOGI("handleEvent: ndp_instance_id = [%d]\n", ndp_instance_id); @@ -3736,7 +3896,6 @@ static int get_svc_hash(unsigned char *svc_name, return WIFI_SUCCESS; } -#ifdef CONFIG_BRCM static int dump_NanEnableRequest(NanEnableRequest* msg) { ALOGI("%s: Dump NanEnableRequest msg:\n", __func__); @@ -3830,10 +3989,19 @@ static int dump_NanEnableRequest(NanEnableRequest* msg) if (msg->config_disc_mac_addr_randomization) { ALOGI("disc_mac_addr_rand_interval_sec =%u\n", msg->disc_mac_addr_rand_interval_sec); } + ALOGI("config_enable_instant_mode =%u\n", msg->config_enable_instant_mode); + if (msg->config_enable_instant_mode) { + ALOGI("enable_instant_mode =%u\n", msg->enable_instant_mode); + } + ALOGI("config_instant_mode_channel=%u\n", msg->config_instant_mode_channel); + if (msg->config_instant_mode_channel) { + ALOGI("instant_mode_channel=%u\n", msg->instant_mode_channel); + } return WIFI_SUCCESS; } +#ifdef CONFIG_BRCM static int dump_NanConfigRequestRequest(NanConfigRequest* msg) { ALOGI("%s: Dump NanConfigRequest msg:\n", __func__); @@ -3895,6 +4063,15 @@ static int dump_NanConfigRequestRequest(NanConfigRequest* msg) if (msg->config_disc_mac_addr_randomization) { ALOGI("disc_mac_addr_rand_interval_sec =%u\n", msg->disc_mac_addr_rand_interval_sec); } + ALOGI("config_enable_instant_mode =%u\n", msg->config_enable_instant_mode); + if (msg->config_enable_instant_mode) { + ALOGI("enable_instant_mode =%u\n", msg->enable_instant_mode); + } + ALOGI("config_instant_mode_channel=%u\n", msg->config_instant_mode_channel); + if (msg->config_instant_mode_channel) { + ALOGI("instant_mode_channel=%u\n", msg->instant_mode_channel); + } + return WIFI_SUCCESS; } @@ -3914,17 +4091,21 @@ static int dump_NanPublishRequest(NanPublishRequest* msg) ALOGI("publish_match_indicator=%u\n", msg->publish_match_indicator); ALOGI("service_responder_policy=%u\n", msg->service_responder_policy); ALOGI("service_name_len=%u\n", msg->service_name_len); - if (msg->service_name_len) + if (msg->service_name_len) { ALOGI("service_name=%s\n", msg->service_name); + } ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len); - if (msg->service_specific_info_len) + if (msg->service_specific_info_len) { ALOGI("service_specific_info=%s\n", msg->service_specific_info); + } ALOGI("rx_match_filter_len=%u\n", msg->rx_match_filter_len); - if (msg->rx_match_filter_len) + if (msg->rx_match_filter_len) { prhex("rx_match_filter", msg->rx_match_filter, msg->rx_match_filter_len); + } ALOGI("tx_match_filter_len=%u\n", msg->tx_match_filter_len); - if (msg->tx_match_filter_len) + if (msg->tx_match_filter_len) { prhex("tx_match_filter", msg->tx_match_filter, msg->tx_match_filter_len); + } ALOGI("rssi_threshold_flag=%u\n", msg->rssi_threshold_flag); ALOGI("connmap=%u\n", msg->connmap); ALOGI("recv_indication_cfg=%u\n", msg->recv_indication_cfg); @@ -3933,8 +4114,9 @@ static int dump_NanPublishRequest(NanPublishRequest* msg) ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk); ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase); ALOGI("scid_len=%u\n", msg->scid_len); - if (msg->scid_len) + if (msg->scid_len) { ALOGI("scid=%s\n", msg->scid); + } ALOGI("NanSdeaCtrlParams NdpType=%u\n", msg->sdea_params.ndp_type); ALOGI("NanSdeaCtrlParams security_cfg=%u\n", msg->sdea_params.security_cfg); ALOGI("NanSdeaCtrlParams ranging_state=%u\n", msg->sdea_params.ranging_state); @@ -3947,8 +4129,9 @@ static int dump_NanPublishRequest(NanPublishRequest* msg) ALOGI("range_response_cfg=%u\n", msg->range_response_cfg.ranging_response); ALOGI("sdea_service_specific_info_len=%u\n", msg->sdea_service_specific_info_len); - if (msg->sdea_service_specific_info_len) + if (msg->sdea_service_specific_info_len) { ALOGI("sdea_service_specific_info=%s\n", msg->sdea_service_specific_info); + } return WIFI_SUCCESS; } @@ -3997,8 +4180,9 @@ static int dump_NanSubscribeRequest(NanSubscribeRequest* msg) ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk); ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase); ALOGI("scid_len=%u\n", msg->scid_len); - if (msg->scid_len) + if (msg->scid_len) { ALOGI("scid=%s\n", msg->scid); + } ALOGI("NanSdeaCtrlParams NdpType=%u\n", msg->sdea_params.ndp_type); ALOGI("NanSdeaCtrlParams security_cfg=%u\n", msg->sdea_params.security_cfg); ALOGI("NanSdeaCtrlParams ranging_state=%u\n", msg->sdea_params.ranging_state); @@ -4065,6 +4249,10 @@ static int dump_NanDataPathInitiatorRequest(NanDataPathInitiatorRequest* msg) ALOGI("key_info: key_type =%u\n", msg->key_info.key_type); ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk); ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase); + ALOGI("scid_len=%u\n", msg->scid_len); + if (msg->scid_len) { + ALOGI("scid=%s\n", msg->scid); + } if (msg->service_name_len) { ALOGI("service_name=%s\n", msg->service_name); } @@ -4095,6 +4283,10 @@ static int dump_NanDataPathIndicationResponse(NanDataPathIndicationResponse* msg ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk); ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase); ALOGI("service_name_len=%u\n", msg->service_name_len); + ALOGI("scid_len=%u\n", msg->scid_len); + if (msg->scid_len) { + ALOGI("scid=%s\n", msg->scid); + } if (msg->service_name_len) { ALOGI("service_name=%s\n", msg->service_name); } @@ -4108,32 +4300,66 @@ void nan_reset_dbg_counters() } /////////////////////////////////////////////////////////////////////////////// -wifi_error nan_enable_request(transaction_id id, - wifi_interface_handle iface, NanEnableRequest* msg) +wifi_error nan_cmn_enabe_request(transaction_id id, + NanMacControl *cmd, NanEnableRequest* msg) { wifi_error ret = WIFI_SUCCESS; - wifi_handle handle = getWifiHandle(iface); - NanRequestType cmdType = NAN_REQUEST_ENABLE; - - ALOGI("Enabling Nan, Handle = %p\n", handle); - #ifdef CONFIG_BRCM // check up nan enable params from Nan manager level dump_NanEnableRequest(msg); #endif /* CONFIG_BRCM */ nan_reset_dbg_counters(); - /* XXX: WAR posting async enable response */ - //NanMacControl *cmd = new NanMacControl(iface, id, (void *)msg, cmdType); - NanMacControl *cmd = (NanMacControl*)(info.nan_mac_control); - NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); - cmd->setType(cmdType); + + cmd->setType(NAN_REQUEST_ENABLE); cmd->setId(id); cmd->setMsg((void *)msg); + ret = (wifi_error)cmd->start(); if (ret != WIFI_SUCCESS) { ALOGE("%s : failed in start, error = %d\n", __func__, ret); } - //cmd->releaseRef(); + + return ret; +} + +wifi_error nan_enable_request(transaction_id id, + wifi_interface_handle iface, NanEnableRequest* msg) +{ + wifi_error ret = WIFI_SUCCESS; + hal_info *h_info = getHalInfo(iface); + + ALOGE("nan_enable_request: nan_state = %d\n", h_info->nan_state); + +#ifdef CHRE_NAN + //check if host NAN is pre-empting CHRE NAN + if (h_info->nan_state == NAN_STATE_CHRE) { + /* notify pre-empt to chre */ + if (h_info->chre_nan_cb.on_chre_nan_rtt_change != NULL) { + h_info->chre_nan_cb.on_chre_nan_rtt_change(CHRE_PREMPTED); + } + /* first disable NAN for chre */ + ret = nan_chre_disable_request(1, iface); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to disable NAN for CHRE ret %d\n", ret); + return ret; + } + } + + /* notify unavailable status to chre */ + if (h_info->chre_nan_cb.on_chre_nan_rtt_change != NULL) { + h_info->chre_nan_cb.on_chre_nan_rtt_change(CHRE_UNAVAILABLE); + } +#endif /* CHRE_NAN */ + + NanMacControl *cmd = (NanMacControl*)(info.nan_mac_control); + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + cmd->setChreNan(0); + ret = nan_cmn_enabe_request(id, cmd, msg); + + if (ret == WIFI_SUCCESS) { + h_info->nan_state = NAN_STATE_AP; + } + return ret; } @@ -4148,16 +4374,40 @@ void nan_dump_dbg_counters() ALOGI("Num Transmit Success %d\n", counters.transmit_txs); } +wifi_error nan_cmn_disable_request(transaction_id id, NanMacControl *mac) +{ + wifi_error ret = WIFI_SUCCESS; + + nan_dump_dbg_counters(); + + mac->setType(NAN_REQUEST_DISABLE); + ret = (wifi_error)mac->cancel(); + if (ret != WIFI_SUCCESS) { + ALOGE("cancel failed, error = %d\n", ret); + } else { + ALOGE("Deinitializing Nan Mac Control = %p\n", mac); + } + mac->releaseRef(); + + return ret; +} wifi_error nan_disable_request(transaction_id id, wifi_interface_handle iface) { - wifi_handle handle = getWifiHandle(iface); - NanRequestType cmdType = NAN_REQUEST_DISABLE; wifi_error ret = WIFI_SUCCESS; + hal_info *h_info = getHalInfo(iface); + + ALOGE("nan_disable_request: nan_state %d\n", h_info->nan_state); + + if (h_info->nan_state == NAN_STATE_CHRE) { + ALOGE("nan_disable_request: Not enabled for AP.. return\n"); + return ret; + } - ALOGI("Disabling Nan, Handle = %p\n", handle); - NanMacControl *cmd = new NanMacControl(iface, id, NULL, cmdType); NanMacControl *mac_prim = (NanMacControl*)(info.nan_mac_control); + NanMacControl *cmd = new NanMacControl(iface, id, NULL, NAN_REQUEST_LAST); + + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); if (id != NAN_MAC_INVALID_TRANSID) { ALOGE("Disable NAN MAC transId= %d\n", id); @@ -4166,17 +4416,15 @@ wifi_error nan_disable_request(transaction_id id, ALOGE("Invalid transId= %d cur= %d\n", id, mac_prim->getId()); } - NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); - - nan_dump_dbg_counters(); - - ret = (wifi_error)cmd->cancel(); - if (ret != WIFI_SUCCESS) { - ALOGE("cancel failed, error = %d\n", ret); - } else { - ALOGE("Deinitializing Nan Mac Control = %p\n", cmd); + cmd->setChreNan(0); + ret = nan_cmn_disable_request(id, cmd); + if (ret == WIFI_SUCCESS) { + h_info->nan_state = NAN_STATE_DISABLED; + /* notify pre-empt / unavailable status to chre */ + if (h_info->chre_nan_cb.on_chre_nan_rtt_change != NULL) { + h_info->chre_nan_cb.on_chre_nan_rtt_change(CHRE_AVAILABLE); + } } - cmd->releaseRef(); return ret; } @@ -4905,6 +5153,15 @@ class NanEventCap : public WifiCommand ndp_request_event.app_info.ndp_app_info[ndp_ind_app_info_len] = '\0'; ALOGI("service info: %s\n", ndp_request_event.app_info.ndp_app_info); + } else if (attr_type == NAN_ATTRIBUTE_SCID_LEN) { + ALOGI("scid length %d\n", it.get_u32()); + ndp_request_event.scid_len= it.get_u32(); + + } else if (attr_type == NAN_ATTRIBUTE_SCID) { + memcpy(ndp_request_event.scid, it.get_data(), + ndp_request_event.scid_len); + ndp_request_event.scid[ndp_request_event.scid_len] = '\0'; + ALOGI("scid: %s\n", ndp_request_event.scid); } } @@ -5264,3 +5521,89 @@ wifi_error nan_data_end(transaction_id id, NAN_DBG_EXIT(); return ret; } + +wifi_error nan_chre_enable_request(transaction_id id, + wifi_interface_handle iface, NanEnableRequest* msg) +{ + wifi_error ret = WIFI_SUCCESS; + NanEnableRequest def_msg; + hal_info *h_info = getHalInfo(iface); + + ALOGI("nan_chre_enable_request: nan_state %d\n", h_info->nan_state); + + if (h_info->nan_state == NAN_STATE_CHRE) { + return WIFI_SUCCESS; + } else if (h_info->nan_state == NAN_STATE_AP) { + ALOGE("nan_chre_enable_request: Nan is enabled for AP. Fail CHRE request\n"); + return WIFI_ERROR_BUSY; + } + + NanMacControl *mac = new NanMacControl(iface, 0, NULL, NAN_REQUEST_LAST); + NULL_CHECK_RETURN(mac, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + + mac->setChreNan(1); + if (msg == NULL) { + /* default enable params */ + ALOGI("Input Enable config is NULL, use default config\n"); + memset(&def_msg, 0, sizeof(def_msg)); + def_msg.hop_count_limit_val = 5; + def_msg.config_2dot4g_support = 1; + def_msg.support_2dot4g_val = 1; + def_msg.config_2dot4g_beacons = 1; + def_msg.beacon_2dot4g_val = 1; + def_msg.config_2dot4g_sdf = 1; + def_msg.sdf_2dot4g_val = 1; + def_msg.config_disc_mac_addr_randomization = true; + def_msg.disc_mac_addr_rand_interval_sec = 0; + def_msg.config_ndpe_attr = false; + ret = nan_cmn_enabe_request(id, mac, &def_msg); + } else { + ret = nan_cmn_enabe_request(id, mac, msg); + } + + if (ret == WIFI_SUCCESS) { + h_info->nan_state = NAN_STATE_CHRE; + } + + return ret; +} + +wifi_error nan_chre_disable_request(transaction_id id, + wifi_interface_handle iface) +{ + wifi_error ret = WIFI_SUCCESS; + hal_info *h_info = getHalInfo(iface); + + ALOGI("nan_chre_disable_request: nan_state %d\n", h_info->nan_state); + + if (h_info->nan_state == NAN_STATE_AP) { + ALOGE("nan_chre_disable_request: Not enabled for CHRE.. return\n"); + return ret; + } + + NanMacControl *cmd = new NanMacControl(iface, id, NULL, NAN_REQUEST_LAST); + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + + cmd->setChreNan(1); + ret = nan_cmn_disable_request(id, cmd); + + if (ret == WIFI_SUCCESS) { + h_info->nan_state = NAN_STATE_DISABLED; + } + + return ret; +} + +wifi_error nan_chre_register_handler(wifi_interface_handle iface, + wifi_chre_handler handler) +{ + wifi_error ret = WIFI_SUCCESS; + hal_info *h_info = getHalInfo(iface); + + if (h_info) { + ALOGE("Registering CHRE handler for Nan Status %p\n", handler.on_chre_nan_rtt_change); + h_info->chre_nan_cb = handler; + } + + return ret; +} diff --git a/bcmdhd/wifi_hal/rtt.cpp b/bcmdhd/wifi_hal/rtt.cpp index 6bb0a49..9716c0e 100644 --- a/bcmdhd/wifi_hal/rtt.cpp +++ b/bcmdhd/wifi_hal/rtt.cpp @@ -43,7 +43,7 @@ #include <log/log.h> #include <utils/String8.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "cpp_bindings.h" diff --git a/bcmdhd/wifi_hal/twt.cpp b/bcmdhd/wifi_hal/twt.cpp index 15bb738..e3dd5bd 100755 --- a/bcmdhd/wifi_hal/twt.cpp +++ b/bcmdhd/wifi_hal/twt.cpp @@ -39,7 +39,7 @@ #include <utils/Log.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "cpp_bindings.h" diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp index c83c482..e250b6d 100755 --- a/bcmdhd/wifi_hal/wifi_hal.cpp +++ b/bcmdhd/wifi_hal/wifi_hal.cpp @@ -47,10 +47,10 @@ #define LOG_TAG "WifiHAL" #include <log/log.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> +#include <hardware_legacy/rtt.h> #include "common.h" #include "cpp_bindings.h" -#include "rtt.h" #include "brcm_version.h" #include <stdio.h> #include <string> @@ -94,6 +94,8 @@ static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle hand static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, u8 enable); static wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask, u32 iface_mode_mask, u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels); +static wifi_error wifi_get_supported_radio_combinations_matrix(wifi_handle handle, + u32 max_size, u32* size, wifi_radio_combination_matrix *radio_combination_matrix); static void wifi_cleanup_dynamic_ifaces(wifi_handle handle); typedef enum wifi_attr { @@ -116,6 +118,13 @@ typedef enum wifi_attr { ANDR_WIFI_ATTRIBUTE_MAX } wifi_attr_t; +enum wifi_radio_combo_attributes { + ANDR_WIFI_ATTRIBUTE_RADIO_COMBO_INVALID = 0, + ANDR_WIFI_ATTRIBUTE_RADIO_COMBO_MATRIX = 1, + // Add more attribute here + ANDR_WIFI_ATTRIBUTE_RADIO_COMBO_MAX +}; + enum wifi_rssi_monitor_attr { RSSI_MONITOR_ATTRIBUTE_INVALID = 0, RSSI_MONITOR_ATTRIBUTE_MAX_RSSI = 1, @@ -331,6 +340,10 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) fn->wifi_set_dtim_config = wifi_set_dtim_config; fn->wifi_get_usable_channels = wifi_get_usable_channels; fn->wifi_trigger_subsystem_restart = wifi_trigger_subsystem_restart; + fn->wifi_get_supported_radio_combinations_matrix = wifi_get_supported_radio_combinations_matrix; + fn->wifi_nan_rtt_chre_enable_request = nan_chre_enable_request; + fn->wifi_nan_rtt_chre_disable_request = nan_chre_disable_request; + fn->wifi_chre_register_handler = nan_chre_register_handler; return WIFI_SUCCESS; } @@ -530,6 +543,7 @@ wifi_error wifi_initialize(wifi_handle *handle) } } else { ALOGI("Not Calling set alert handler as global_iface is NULL"); + return WIFI_ERROR_UNKNOWN; } return WIFI_SUCCESS; } @@ -617,7 +631,6 @@ void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler) } hal_info *info = getHalInfo(handle); - char buf[64]; wifi_error result; int numIfaceHandles = 0; @@ -1479,6 +1492,93 @@ protected: } }; +///////////////////////////////////////////////////////////////////// +class GetRadioComboCommand : public WifiCommand { +private: + wifi_radio_combination_matrix *rcmatrix; + u32* rc_size; + u32 set_size_max; + int ret = 0; + +public: + GetRadioComboCommand(wifi_interface_handle handle, u32 max_size, u32* size, + wifi_radio_combination_matrix *radio_combination_matrix) + : WifiCommand("GetRadioComboCommand", handle, 0), rcmatrix(radio_combination_matrix), + rc_size(size), set_size_max(max_size) + { + } + + virtual int createRequest(WifiRequest& mMsg) { + ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_RADIO_COMBO_MATRIX); + if (ret < 0) { + ALOGE("Can't create message to send to driver - %d", ret); + } + nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA); + mMsg.attr_end(data); + + return ret; + } + + int start() { + WifiRequest request(familyId(), ifaceId()); + ret = createRequest(request); + if (ret < 0) { + ALOGE("Request failed for radio_combo_matrix, result = %d", ret); + return ret; + } + ret = requestResponse(request); + if (ret < 0) { + ALOGE("Request Response failed for radio_combo_matrix, result = %d", ret); + return ret; + } + ALOGD("Done! %s", __FUNCTION__); + return ret; + } + +protected: + virtual int handleResponse(WifiEvent& reply) { + ALOGD("In GetRadioComboCommand::handleResponse"); + if (reply.get_cmd() != NL80211_CMD_VENDOR) { + ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); + return NL_SKIP; + } + + int id = reply.get_vendor_id(); + int subcmd = reply.get_vendor_subcmd(); + + nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); + int len = reply.get_vendor_data_len(); + + ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); + if (vendor_data == NULL || len == 0) { + ALOGE("no vendor data in GetRadioComboCommand response; ignoring it"); + return NL_SKIP; + } + + for (nl_iterator it(vendor_data); it.has_next(); it.next()) { + if (it.get_type() == ANDR_WIFI_ATTRIBUTE_RADIO_COMBO_MATRIX) { + void *data = it.get_data(); + *rc_size = it.get_len(); + if (!data || !*rc_size) { + ALOGE("Buffers pointers not set"); + return NL_SKIP; + } + if (set_size_max < *rc_size) { + ALOGE("Unexpected buffers size"); + return NL_SKIP; + } + memcpy(rcmatrix, data, min(len, *rc_size)); + } else { + ALOGW("Ignoring invalid attribute type = %d, size = %d", + it.get_type(), it.get_len()); + } + } + + ALOGD("GetRadioComboCommand::Success"); + return NL_OK; + } +}; +///////////////////////////////////////////////////////////////////// class SetLatencyModeCommand : public WifiCommand { private: @@ -1760,6 +1860,27 @@ wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_siz return (wifi_error) command.requestResponse(); } +wifi_error wifi_get_supported_radio_combinations_matrix(wifi_handle handle, + u32 max_size, u32* size, wifi_radio_combination_matrix *radio_combination_matrix) +{ + int numIfaceHandles = 0; + wifi_interface_handle *ifaceHandles = NULL; + wifi_interface_handle wlan0Handle; + + wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles); + GetRadioComboCommand *cmd = new GetRadioComboCommand(wlan0Handle, max_size, + size, radio_combination_matrix); + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + wifi_error result = (wifi_error)cmd->start(); + if (result == WIFI_SUCCESS) { + ALOGD("Get radio combo matrix success"); + } else { + ALOGE("Get radio combo matrix failed\n"); + } + cmd->releaseRef(); + return result; +} + wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui) { SetPnoMacAddrOuiCommand command(handle, scan_oui); diff --git a/bcmdhd/wifi_hal/wifi_logger.cpp b/bcmdhd/wifi_hal/wifi_logger.cpp index 85cf0e7..a605b85 100755 --- a/bcmdhd/wifi_hal/wifi_logger.cpp +++ b/bcmdhd/wifi_hal/wifi_logger.cpp @@ -45,7 +45,7 @@ #include <log/log.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "cpp_bindings.h" #include <sys/stat.h> @@ -72,7 +72,9 @@ typedef enum { LOGGER_FILE_DUMP_DONE_IND, LOGGER_SET_HAL_START, LOGGER_HAL_STOP, - LOGGER_SET_HAL_PID + LOGGER_SET_HAL_PID, + LOGGER_SET_TPUT_DEBUG_DUMP_CMD, + LOGGER_GET_BUF_RING_MAP } DEBUG_SUB_COMMAND; #define MAX_NV_FILE 4 @@ -118,6 +120,8 @@ typedef enum { LOGGER_ATTRIBUTE_PKT_FATE_NUM = 17, LOGGER_ATTRIBUTE_PKT_FATE_DATA = 18, LOGGER_ATTRIBUTE_HANG_REASON = 19, + LOGGER_ATTRIBUTE_BUF_RING_NUM = 20, + LOGGER_ATTRIBUTE_BUF_RING_MAP = 21, /* Add new attributes just above this */ LOGGER_ATTRIBUTE_MAX } LOGGER_ATTRIBUTE; @@ -137,6 +141,7 @@ typedef enum { GET_RING_STATUS, GET_FEATURE, START_RING_LOG, + GET_BUF_RING_MAP, } GetCmdType; typedef enum { @@ -189,6 +194,323 @@ typedef enum { #define HAL_START_REQUEST_ID 2 #define HAL_RESTART_ID 3 #define FILE_NAME_LEN 256 +#define RING_NAME_LEN 32 +#if defined(RING_DUMP) +/* Loglevel */ +#define DUMP_DEBUG(x) +#define DUMP_INFO(x) ALOGI x +#define FILE_DUMP_REQUEST_ID 2 +#define C2S(x) case x: return #x; +static const char *EWP_EventAttrToString(int len_attr); +static const char *EWP_CmdAttrToString(int data_attr); + +typedef struct buf_data { + u32 ver; /* version of struct */ + u32 len; /* Total len */ + /* size of each buffer in case of split buffers (0 - single buffer). */ + u32 buf_threshold; + const void *data_buf[1]; /* array of user space buffer pointers.*/ +} buf_data_t; + +/* Attributes associated with GOOGLE_FILE_DUMP_EVENT */ +typedef enum { + DUMP_LEN_ATTR_INVALID = 0, + DUMP_LEN_ATTR_MEMDUMP = 1, + DUMP_LEN_ATTR_SSSR_C0_BEFORE = 2, + DUMP_LEN_ATTR_SSSR_C0_AFTER = 3, + DUMP_LEN_ATTR_SSSR_C1_BEFORE = 4, + DUMP_LEN_ATTR_SSSR_C1_AFTER = 5, + DUMP_LEN_ATTR_SSSR_C2_BEFORE = 6, + DUMP_LEN_ATTR_SSSR_C2_AFTER = 7, + DUMP_LEN_ATTR_SSSR_DIG_BEFORE = 8, + DUMP_LEN_ATTR_SSSR_DIG_AFTER = 9, + DUMP_LEN_ATTR_TIMESTAMP = 10, + DUMP_LEN_ATTR_GENERAL_LOG = 11, + DUMP_LEN_ATTR_ECNTRS = 12, + DUMP_LEN_ATTR_SPECIAL_LOG = 13, + DUMP_LEN_ATTR_DHD_DUMP = 14, + DUMP_LEN_ATTR_EXT_TRAP = 15, + DUMP_LEN_ATTR_HEALTH_CHK = 16, + DUMP_LEN_ATTR_PRESERVE_LOG = 17, + DUMP_LEN_ATTR_COOKIE = 18, + DUMP_LEN_ATTR_FLOWRING_DUMP = 19, + DUMP_LEN_ATTR_PKTLOG = 20, + DUMP_LEN_ATTR_PKTLOG_DEBUG = 21, + DUMP_FILENAME_ATTR_DEBUG_DUMP = 22, + DUMP_FILENAME_ATTR_MEM_DUMP = 23, + DUMP_FILENAME_ATTR_SSSR_CORE_0_BEFORE_DUMP = 24, + DUMP_FILENAME_ATTR_SSSR_CORE_0_AFTER_DUMP = 25, + DUMP_FILENAME_ATTR_SSSR_CORE_1_BEFORE_DUMP = 26, + DUMP_FILENAME_ATTR_SSSR_CORE_1_AFTER_DUMP = 27, + DUMP_FILENAME_ATTR_SSSR_CORE_2_BEFORE_DUMP = 28, + DUMP_FILENAME_ATTR_SSSR_CORE_2_AFTER_DUMP = 29, + DUMP_FILENAME_ATTR_SSSR_DIG_BEFORE_DUMP = 30, + DUMP_FILENAME_ATTR_SSSR_DIG_AFTER_DUMP = 31, + DUMP_FILENAME_ATTR_PKTLOG_DUMP = 32, + DUMP_FILENAME_ATTR_PKTLOG_DEBUG_DUMP = 33, + DUMP_LEN_ATTR_STATUS_LOG = 34, + DUMP_LEN_ATTR_AXI_ERROR = 35, + DUMP_FILENAME_ATTR_AXI_ERROR_DUMP = 36, + DUMP_LEN_ATTR_RTT_LOG = 37, + DUMP_LEN_ATTR_SDTC_ETB_DUMP = 38, + DUMP_FILENAME_ATTR_SDTC_ETB_DUMP = 39, + DUMP_LEN_ATTR_PKTID_MAP_LOG = 40, + DUMP_LEN_ATTR_PKTID_UNMAP_LOG = 41, + DUMP_LEN_ATTR_EWP_HW_INIT_LOG = 42, + DUMP_LEN_ATTR_EWP_HW_MOD_DUMP = 43, + DUMP_LEN_ATTR_EWP_HW_REG_DUMP = 44, + /* Please add new attributes from here to sync up old DHD */ + DUMP_EVENT_ATTR_MAX = 45, +} EWP_DUMP_EVENT_ATTRIBUTE; + +/* Attributes associated with DEBUG_GET_DUMP_BUF */ +typedef enum { + DUMP_BUF_ATTR_INVALID = 0, + DUMP_BUF_ATTR_MEMDUMP = 1, + DUMP_BUF_ATTR_SSSR_C0_BEFORE = 2, + DUMP_BUF_ATTR_SSSR_C0_AFTER = 3, + DUMP_BUF_ATTR_SSSR_C1_BEFORE = 4, + DUMP_BUF_ATTR_SSSR_C1_AFTER = 5, + DUMP_BUF_ATTR_SSSR_C2_BEFORE = 6, + DUMP_BUF_ATTR_SSSR_C2_AFTER = 7, + DUMP_BUF_ATTR_SSSR_DIG_BEFORE = 8, + DUMP_BUF_ATTR_SSSR_DIG_AFTER = 9, + DUMP_BUF_ATTR_TIMESTAMP = 10, + DUMP_BUF_ATTR_GENERAL_LOG = 11, + DUMP_BUF_ATTR_ECNTRS = 12, + DUMP_BUF_ATTR_SPECIAL_LOG = 13, + DUMP_BUF_ATTR_DHD_DUMP = 14, + DUMP_BUF_ATTR_EXT_TRAP = 15, + DUMP_BUF_ATTR_HEALTH_CHK = 16, + DUMP_BUF_ATTR_PRESERVE_LOG = 17, + DUMP_BUF_ATTR_COOKIE = 18, + DUMP_BUF_ATTR_FLOWRING_DUMP = 19, + DUMP_BUF_ATTR_PKTLOG = 20, + DUMP_BUF_ATTR_PKTLOG_DEBUG = 21, + DUMP_BUF_ATTR_STATUS_LOG = 22, + DUMP_BUF_ATTR_AXI_ERROR = 23, + DUMP_BUF_ATTR_RTT_LOG = 24, + DUMP_BUF_ATTR_SDTC_ETB_DUMP = 25, + DUMP_BUF_ATTR_PKTID_MAP_LOG = 26, + DUMP_BUF_ATTR_PKTID_UNMAP_LOG = 27, + DUMP_BUF_ATTR_EWP_HW_INIT_LOG = 28, + DUMP_BUF_ATTR_EWP_HW_MOD_DUMP = 29, + DUMP_BUF_ATTR_EWP_HW_REG_DUMP = 30, + /* Please add new attributes from here to sync up old DHD */ + DUMP_BUF_ATTR_MAX = 31, +} EWP_DUMP_CMD_ATTRIBUTE; + +typedef enum { + DUMP_TYPE_MEM_DUMP = 0, + DUMP_TYPE_DEBUG_DUMP = 1, + DUMP_TYPE_SSSR_CORE0_BEF_DUMP = 2, + DUMP_TYPE_SSSR_CORE0_AFT_DUMP = 3, + DUMP_TYPE_SSSR_CORE1_BEF_DUMP = 4, + DUMP_TYPE_SSSR_CORE1_AFT_DUMP = 5, + DUMP_TYPE_SSSR_CORE2_BEF_DUMP = 6, + DUMP_TYPE_SSSR_CORE2_AFT_DUMP = 7, + DUMP_TYPE_SSSR_DIG_BEF_DUMP = 8, + DUMP_TYPE_SSSR_DIG_AFT_DUMP = 9, + DUMP_TYPE_PKTLOG_DUMP = 10, + DUMP_TYPE_PKTLOG_DEBUG_DUMP = 11, + DUMP_TYPE_AXI_ERROR_DUMP = 12, + DUMP_TYPE_D2H_MINI_DUMP = 13, + DUMP_TYPE_SDTC_ETB_DUMP = 14, + /* Please add new attributes from here to sync up old DHD */ + DUMP_TYPE_MAX = 15, +} EWP_DUMP_TYPE; + +/* Struct for table which has len_attr, data_attr and dump file type attr */ +typedef struct logger_attr_entry { + u8 attr_type; /* Type of attribute */ + u8 buf_attr; /* Buffer associated with the attribute */ + u8 dump_type; /* Each attribute will be linked to a dump type */ +} logger_attr_entry_t; + +logger_attr_entry_t attr_lookup_tbl[] = { + /* Mem Dump Block */ + {DUMP_FILENAME_ATTR_MEM_DUMP, 0, DUMP_TYPE_MEM_DUMP}, + {DUMP_LEN_ATTR_MEMDUMP, DUMP_BUF_ATTR_MEMDUMP, DUMP_TYPE_MEM_DUMP}, + /* SSSR Dump Block */ + {DUMP_FILENAME_ATTR_SSSR_CORE_0_BEFORE_DUMP, 0, DUMP_TYPE_SSSR_CORE0_BEF_DUMP}, + {DUMP_LEN_ATTR_SSSR_C0_BEFORE, DUMP_BUF_ATTR_SSSR_C0_BEFORE, DUMP_TYPE_SSSR_CORE0_BEF_DUMP}, + + {DUMP_FILENAME_ATTR_SSSR_CORE_0_AFTER_DUMP, 0, DUMP_TYPE_SSSR_CORE0_AFT_DUMP}, + {DUMP_LEN_ATTR_SSSR_C0_AFTER, DUMP_BUF_ATTR_SSSR_C0_AFTER, DUMP_TYPE_SSSR_CORE0_AFT_DUMP}, + + {DUMP_FILENAME_ATTR_SSSR_CORE_1_BEFORE_DUMP, 0, DUMP_TYPE_SSSR_CORE1_BEF_DUMP}, + {DUMP_LEN_ATTR_SSSR_C1_BEFORE, DUMP_BUF_ATTR_SSSR_C1_BEFORE, DUMP_TYPE_SSSR_CORE1_BEF_DUMP}, + + {DUMP_FILENAME_ATTR_SSSR_CORE_1_AFTER_DUMP, 0, DUMP_TYPE_SSSR_CORE1_AFT_DUMP}, + {DUMP_LEN_ATTR_SSSR_C1_AFTER, DUMP_BUF_ATTR_SSSR_C1_AFTER, DUMP_TYPE_SSSR_CORE1_AFT_DUMP}, + + {DUMP_FILENAME_ATTR_SSSR_CORE_2_BEFORE_DUMP, 0, DUMP_TYPE_SSSR_CORE2_BEF_DUMP}, + {DUMP_LEN_ATTR_SSSR_C2_BEFORE, DUMP_BUF_ATTR_SSSR_C2_BEFORE, DUMP_TYPE_SSSR_CORE2_BEF_DUMP}, + + {DUMP_FILENAME_ATTR_SSSR_CORE_2_AFTER_DUMP, 0, DUMP_TYPE_SSSR_CORE2_AFT_DUMP}, + {DUMP_LEN_ATTR_SSSR_C2_AFTER, DUMP_BUF_ATTR_SSSR_C2_AFTER, DUMP_TYPE_SSSR_CORE2_AFT_DUMP}, + + {DUMP_FILENAME_ATTR_SSSR_DIG_BEFORE_DUMP, 0, DUMP_TYPE_SSSR_DIG_BEF_DUMP}, + {DUMP_LEN_ATTR_SSSR_DIG_BEFORE, DUMP_BUF_ATTR_SSSR_DIG_BEFORE, DUMP_TYPE_SSSR_DIG_BEF_DUMP}, + + {DUMP_FILENAME_ATTR_SSSR_DIG_AFTER_DUMP, 0, DUMP_TYPE_SSSR_DIG_AFT_DUMP}, + {DUMP_LEN_ATTR_SSSR_DIG_AFTER, DUMP_BUF_ATTR_SSSR_DIG_AFTER, DUMP_TYPE_SSSR_DIG_AFT_DUMP}, + + /* Debug Dump Block */ + {DUMP_FILENAME_ATTR_DEBUG_DUMP, 0, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_TIMESTAMP, DUMP_BUF_ATTR_TIMESTAMP, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_GENERAL_LOG, DUMP_BUF_ATTR_GENERAL_LOG, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_ECNTRS, DUMP_BUF_ATTR_ECNTRS, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_SPECIAL_LOG, DUMP_BUF_ATTR_SPECIAL_LOG, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_DHD_DUMP, DUMP_BUF_ATTR_DHD_DUMP, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_EXT_TRAP, DUMP_BUF_ATTR_EXT_TRAP, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_HEALTH_CHK, DUMP_BUF_ATTR_HEALTH_CHK, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_PRESERVE_LOG, DUMP_BUF_ATTR_PRESERVE_LOG, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_COOKIE, DUMP_BUF_ATTR_COOKIE, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_FLOWRING_DUMP, DUMP_BUF_ATTR_FLOWRING_DUMP, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_STATUS_LOG, DUMP_BUF_ATTR_STATUS_LOG, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_RTT_LOG, DUMP_BUF_ATTR_RTT_LOG, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_PKTID_MAP_LOG, DUMP_BUF_ATTR_PKTID_MAP_LOG, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_PKTID_UNMAP_LOG, DUMP_BUF_ATTR_PKTID_UNMAP_LOG, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_EWP_HW_INIT_LOG, DUMP_BUF_ATTR_EWP_HW_INIT_LOG, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_EWP_HW_MOD_DUMP, DUMP_BUF_ATTR_EWP_HW_MOD_DUMP, DUMP_TYPE_DEBUG_DUMP}, + {DUMP_LEN_ATTR_EWP_HW_REG_DUMP, DUMP_BUF_ATTR_EWP_HW_REG_DUMP, DUMP_TYPE_DEBUG_DUMP}, + + /* PKT log dump block */ + {DUMP_FILENAME_ATTR_PKTLOG_DUMP, 0, DUMP_TYPE_PKTLOG_DUMP}, + {DUMP_LEN_ATTR_PKTLOG, DUMP_BUF_ATTR_PKTLOG, DUMP_TYPE_PKTLOG_DUMP}, + {DUMP_FILENAME_ATTR_PKTLOG_DEBUG_DUMP, 0, DUMP_TYPE_PKTLOG_DEBUG_DUMP}, + {DUMP_LEN_ATTR_PKTLOG_DEBUG, DUMP_BUF_ATTR_PKTLOG_DEBUG, DUMP_TYPE_PKTLOG_DEBUG_DUMP}, + /* AXI error log dump block */ + {DUMP_FILENAME_ATTR_AXI_ERROR_DUMP, 0, DUMP_TYPE_AXI_ERROR_DUMP}, + {DUMP_LEN_ATTR_AXI_ERROR, DUMP_BUF_ATTR_AXI_ERROR, DUMP_TYPE_AXI_ERROR_DUMP}, + /* SDTC etb log dump block */ + {DUMP_FILENAME_ATTR_SDTC_ETB_DUMP, 0, DUMP_TYPE_SDTC_ETB_DUMP}, + {DUMP_LEN_ATTR_SDTC_ETB_DUMP, DUMP_BUF_ATTR_SDTC_ETB_DUMP, DUMP_TYPE_SDTC_ETB_DUMP}, + {DUMP_EVENT_ATTR_MAX, 0, 0}, +}; + +static const char *EWP_EventAttrToString(int len_attr) +{ + switch (len_attr) { + C2S(DUMP_LEN_ATTR_MEMDUMP) + C2S(DUMP_LEN_ATTR_SSSR_C0_BEFORE) + C2S(DUMP_LEN_ATTR_SSSR_C0_AFTER) + C2S(DUMP_LEN_ATTR_SSSR_C1_BEFORE) + C2S(DUMP_LEN_ATTR_SSSR_C1_AFTER) + C2S(DUMP_LEN_ATTR_SSSR_C2_BEFORE) + C2S(DUMP_LEN_ATTR_SSSR_C2_AFTER) + C2S(DUMP_LEN_ATTR_SSSR_DIG_BEFORE) + C2S(DUMP_LEN_ATTR_SSSR_DIG_AFTER) + C2S(DUMP_LEN_ATTR_TIMESTAMP) + C2S(DUMP_LEN_ATTR_GENERAL_LOG) + C2S(DUMP_LEN_ATTR_ECNTRS) + C2S(DUMP_LEN_ATTR_SPECIAL_LOG) + C2S(DUMP_LEN_ATTR_DHD_DUMP) + C2S(DUMP_LEN_ATTR_EXT_TRAP) + C2S(DUMP_LEN_ATTR_HEALTH_CHK) + C2S(DUMP_LEN_ATTR_PRESERVE_LOG) + C2S(DUMP_LEN_ATTR_COOKIE) + C2S(DUMP_LEN_ATTR_FLOWRING_DUMP) + C2S(DUMP_LEN_ATTR_PKTLOG) + C2S(DUMP_LEN_ATTR_PKTLOG_DEBUG) + C2S(DUMP_LEN_ATTR_STATUS_LOG) + C2S(DUMP_FILENAME_ATTR_DEBUG_DUMP) + C2S(DUMP_FILENAME_ATTR_MEM_DUMP) + C2S(DUMP_FILENAME_ATTR_SSSR_CORE_0_BEFORE_DUMP) + C2S(DUMP_FILENAME_ATTR_SSSR_CORE_0_AFTER_DUMP) + C2S(DUMP_FILENAME_ATTR_SSSR_CORE_1_BEFORE_DUMP) + C2S(DUMP_FILENAME_ATTR_SSSR_CORE_1_AFTER_DUMP) + C2S(DUMP_FILENAME_ATTR_SSSR_CORE_2_BEFORE_DUMP) + C2S(DUMP_FILENAME_ATTR_SSSR_CORE_2_AFTER_DUMP) + C2S(DUMP_FILENAME_ATTR_SSSR_DIG_BEFORE_DUMP) + C2S(DUMP_FILENAME_ATTR_SSSR_DIG_AFTER_DUMP) + C2S(DUMP_FILENAME_ATTR_PKTLOG_DUMP) + C2S(DUMP_FILENAME_ATTR_PKTLOG_DEBUG_DUMP) + C2S(DUMP_LEN_ATTR_AXI_ERROR) + C2S(DUMP_FILENAME_ATTR_AXI_ERROR_DUMP) + C2S(DUMP_LEN_ATTR_RTT_LOG) + C2S(DUMP_FILENAME_ATTR_SDTC_ETB_DUMP) + C2S(DUMP_LEN_ATTR_SDTC_ETB_DUMP) + C2S(DUMP_LEN_ATTR_PKTID_MAP_LOG) + C2S(DUMP_LEN_ATTR_PKTID_UNMAP_LOG) + C2S(DUMP_LEN_ATTR_EWP_HW_INIT_LOG) + C2S(DUMP_LEN_ATTR_EWP_HW_MOD_DUMP) + C2S(DUMP_LEN_ATTR_EWP_HW_REG_DUMP) + default: + return "DUMP_LEN_ATTR_INVALID"; + } +} + +static const char *EWP_CmdAttrToString(int attr) +{ + switch (attr) { + C2S(DUMP_BUF_ATTR_MEMDUMP) + C2S(DUMP_BUF_ATTR_SSSR_C0_BEFORE) + C2S(DUMP_BUF_ATTR_SSSR_C0_AFTER) + C2S(DUMP_BUF_ATTR_SSSR_C1_BEFORE) + C2S(DUMP_BUF_ATTR_SSSR_C1_AFTER) + C2S(DUMP_BUF_ATTR_SSSR_C2_BEFORE) + C2S(DUMP_BUF_ATTR_SSSR_C2_AFTER) + C2S(DUMP_BUF_ATTR_SSSR_DIG_BEFORE) + C2S(DUMP_BUF_ATTR_SSSR_DIG_AFTER) + C2S(DUMP_BUF_ATTR_TIMESTAMP) + C2S(DUMP_BUF_ATTR_GENERAL_LOG) + C2S(DUMP_BUF_ATTR_ECNTRS) + C2S(DUMP_BUF_ATTR_SPECIAL_LOG) + C2S(DUMP_BUF_ATTR_DHD_DUMP) + C2S(DUMP_BUF_ATTR_EXT_TRAP) + C2S(DUMP_BUF_ATTR_HEALTH_CHK) + C2S(DUMP_BUF_ATTR_PRESERVE_LOG) + C2S(DUMP_BUF_ATTR_COOKIE) + C2S(DUMP_BUF_ATTR_FLOWRING_DUMP) + C2S(DUMP_BUF_ATTR_PKTLOG) + C2S(DUMP_BUF_ATTR_PKTLOG_DEBUG) + C2S(DUMP_BUF_ATTR_STATUS_LOG) + C2S(DUMP_BUF_ATTR_AXI_ERROR) + C2S(DUMP_BUF_ATTR_RTT_LOG) + C2S(DUMP_BUF_ATTR_SDTC_ETB_DUMP) + C2S(DUMP_BUF_ATTR_PKTID_MAP_LOG) + C2S(DUMP_BUF_ATTR_PKTID_UNMAP_LOG) + C2S(DUMP_BUF_ATTR_EWP_HW_INIT_LOG) + C2S(DUMP_BUF_ATTR_EWP_HW_MOD_DUMP) + C2S(DUMP_BUF_ATTR_EWP_HW_REG_DUMP) + default: + return "DUMP_BUF_ATTR_INVALID"; + } +} + +/* Return index for matching buffer attribute */ +static int logger_attr_buffer_lookup(u8 attr) { + for (u8 i = 0; i < ARRAYSIZE(attr_lookup_tbl); i++) { + if (attr == attr_lookup_tbl[i].buf_attr) { + return i; + } + } + ALOGE("Lookup for buf attr = %s failed\n", + EWP_CmdAttrToString(attr)); + return -1; +} + +/* Return index matching the length attribute */ +static int logger_attr_lookup(u8 attr) { + for (u8 i = 0; i < ARRAYSIZE(attr_lookup_tbl); i++) { + if (attr == attr_lookup_tbl[i].attr_type) { + return i; + } + } + ALOGE("Lookup for len attr = %s failed\n", + EWP_EventAttrToString(attr)); + return -1; +} +#endif /* RING_DUMP */ + +#define DBGRING_NAME_MAX 32 //Copy from legacy hal +typedef struct wifi_buf_ring_map_entry { + uint32_t type; + uint32_t ring_id; + char ring_name[DBGRING_NAME_MAX]; +} wifi_buf_ring_map_entry_t; typedef struct { char hw_id[PROPERTY_VALUE_MAX]; @@ -196,19 +518,25 @@ typedef struct { } sku_info_t; sku_info_t sku_table[] = { - { {"G9S9B"}, {"MMW"} }, - { {"G8V0U"}, {"MMW"} }, - { {"GFQM1"}, {"MMW"} }, - { {"GB62Z"}, {"MMW"} }, - { {"GB7N6"}, {"ROW"} }, - { {"GLU0G"}, {"ROW"} }, - { {"GNA8F"}, {"ROW"} }, - { {"GX7AS"}, {"ROW"} }, - { {"GR1YH"}, {"JPN"} }, - { {"GF5KQ"}, {"JPN"} }, - { {"GPQ72"}, {"JPN"} }, - { {"GB17L"}, {"JPN"} }, - { {"G1AZG"}, {"EU"} } + { {"G9S9B"}, {"MMW"} }, + { {"G8V0U"}, {"MMW"} }, + { {"GFQM1"}, {"MMW"} }, + { {"GB62Z"}, {"MMW"} }, + { {"GE2AE"}, {"MMW"} }, + { {"GQML3"}, {"MMW"} }, + { {"GB7N6"}, {"ROW"} }, + { {"GLU0G"}, {"ROW"} }, + { {"GNA8F"}, {"ROW"} }, + { {"GX7AS"}, {"ROW"} }, + { {"GP4BC"}, {"ROW"} }, + { {"GVU6C"}, {"ROW"} }, + { {"GR1YH"}, {"JPN"} }, + { {"GF5KQ"}, {"JPN"} }, + { {"GPQ72"}, {"JPN"} }, + { {"GB17L"}, {"JPN"} }, + { {"GFE4J"}, {"JPN"} }, + { {"G03Z5"}, {"JPN"} }, + { {"G1AZG"}, {"EU"} } }; /////////////////////////////////////////////////////////////////////////////// class DebugCommand : public WifiCommand @@ -217,6 +545,8 @@ class DebugCommand : public WifiCommand int *mBuffSize; u32 *mNumRings; wifi_ring_buffer_status *mStatus; + u32 *mNumMaps; + wifi_buf_ring_map_entry_t *mMaps; unsigned int *mSupport; u32 mVerboseLevel; u32 mFlags; @@ -290,6 +620,14 @@ public: mRingName = NULL; } + // constructor for buf ring map + DebugCommand(wifi_interface_handle iface, u32 *num_maps, + wifi_buf_ring_map_entry_t *map, GetCmdType cmdType) + : WifiCommand("DebugCommand", iface, 0), mNumMaps(num_maps), mMaps(map), mType(cmdType) + { + memset(mMaps, 0, sizeof(wifi_buf_ring_map_entry_t) * (*mNumMaps)); + } + // constructor for ring params DebugCommand(wifi_interface_handle iface, u32 verbose_level, u32 flags, u32 max_interval_sec, u32 min_data_size, char *ring_name, GetCmdType cmdType) @@ -428,6 +766,16 @@ public: break; } + case GET_BUF_RING_MAP: + { + result = request.create(GOOGLE_OUI, LOGGER_GET_BUF_RING_MAP); + if (result != WIFI_SUCCESS) { + ALOGE("Failed to create get ring status request; result = %d", result); + return result; + } + break; + } + case START_RING_LOG: result = createRingRequest(request); break; @@ -538,6 +886,52 @@ public: break; } + case GET_BUF_RING_MAP: + { + nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); + int len = reply.get_vendor_data_len(); + wifi_buf_ring_map_entry_t *map(mMaps); + + if (vendor_data == NULL || len == 0) { + ALOGE("No Debug data found"); + return NL_SKIP; + } + + nl_iterator it(vendor_data); + if (it.get_type() == LOGGER_ATTRIBUTE_BUF_RING_NUM) { + unsigned int num_maps = it.get_u32(); + if (*mNumMaps < num_maps) { + ALOGE("Not enough status buffers provided, available: %d required: %d", + *mNumMaps, num_maps); + } else { + *mNumMaps = num_maps; + } + } else { + ALOGE("Unknown attribute: %d expecting %d", + it.get_type(), LOGGER_ATTRIBUTE_BUF_RING_NUM); + return NL_SKIP; + } + + it.next(); + for (unsigned int i = 0; it.has_next() && i < *mNumMaps; it.next()) { + if (it.get_type() == LOGGER_ATTRIBUTE_BUF_RING_MAP) { + if (it.get_len() > sizeof(wifi_buf_ring_map_entry_t)) { + ALOGE("GET_BUF_RING_MAP: unexpected len = %d, dest len = %lu", + it.get_len(), sizeof(wifi_buf_ring_map_entry_t)); + return NL_SKIP; + } else { + memcpy(map, it.get_data(), sizeof(wifi_buf_ring_map_entry_t)); + } + i++; + map++; + } else { + ALOGW("Ignoring invalid attribute type = %d, size = %d", + it.get_type(), it.get_len()); + } + } + break; + } + default: ALOGW("Unknown Debug command"); } @@ -627,6 +1021,8 @@ wifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level, u32 flags, u32 max_interval_sec, u32 min_data_size, char *ring_name) { if (ring_name) { + ALOGE("Ring name: level:%d sec:%d ring_name:%s", + verbose_level, max_interval_sec, ring_name); DebugCommand *cmd = new DebugCommand(iface, verbose_level, flags, max_interval_sec, min_data_size, ring_name, START_RING_LOG); NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); @@ -677,7 +1073,7 @@ public: unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT); ALOGV("Hal preInit Failed to put pid= %d", result); return result; - } + } request.attr_end(data); @@ -757,10 +1153,10 @@ public: if (mHandler.on_ring_buffer_data) { /* Skip msg header. Retrieved log */ char *pBuff; - wifi_ring_buffer_entry *buffer_entry = + wifi_ring_buffer_entry *buffer_entry = (wifi_ring_buffer_entry *) buffer; pBuff = (char *) (buffer_entry + 1); - (*mHandler.on_ring_buffer_data)((char *)status.name, pBuff, + (*mHandler.on_ring_buffer_data)((char *)status.name, pBuff, buffer_entry->entry_size, &status); } } else { @@ -775,7 +1171,7 @@ wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface, wifi_ring_buffer_data_handler handler) { wifi_handle handle = getWifiHandle(iface); - ALOGV("Loghandler start, handle = %p", handle); + ALOGE("Loghandler start, handle = %p", handle); SetLogHandler *cmd = new SetLogHandler(iface, id, handler); NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); @@ -790,13 +1186,17 @@ wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface, cmd->releaseRef(); return result; } + +#ifdef RING_DUMP + wifi_start_ring_dump(iface, handler); +#endif /* RING_DUMP */ return result; } wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface) { wifi_handle handle = getWifiHandle(iface); - ALOGV("Loghandler reset, wifi_request_id = %d, handle = %p", id, handle); + ALOGE("Loghandler reset, wifi_request_id = %d, handle = %p", id, handle); if (id == -1) { wifi_ring_buffer_data_handler handler; @@ -806,6 +1206,10 @@ wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle ifac NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); cmd->cancel(); cmd->releaseRef(); + +#ifdef RING_DUMP + wifi_stop_ring_dump(iface, handler); +#endif /* RING_DUMP */ return WIFI_SUCCESS; } @@ -984,7 +1388,7 @@ public: : WifiCommand("SetRestartHandler", handle, id), mHandler(handler), mBuff(NULL) { } int start() { - ALOGI("Start Restart Handler handler:%p", mHandler); + ALOGI("Start Restart Handler handler"); registerVendorHandler(BRCM_OUI, BRCM_VENDOR_EVENT_HANGED); return WIFI_SUCCESS; } @@ -1171,6 +1575,338 @@ class HalInit : public WifiCommand } }; +#ifdef RING_DUMP +/////////////////////////////////////////////////////////////////////////////// +class RingDump : public WifiCommand +{ + int mLargestBuffSize; + char *mBuff; + int mErrCode; + int mNumMaps; + wifi_buf_ring_map_entry_t *mMap; + int attr_type_len[DUMP_EVENT_ATTR_MAX]; + char *ring_name[DUMP_BUF_ATTR_MAX]; + wifi_ring_buffer_data_handler mHandle; + +public: + RingDump(wifi_interface_handle iface, int id, int num_maps, wifi_buf_ring_map_entry_t *map, + wifi_ring_buffer_data_handler ring_handle) + : WifiCommand("RingDump", iface, id), mLargestBuffSize(0), mBuff(NULL), + mErrCode(0), mNumMaps(num_maps), mMap(map), mHandle(ring_handle) + { + memset(attr_type_len, 0, sizeof(attr_type_len)); + for (int i = 0; i < DUMP_BUF_ATTR_MAX; i++) { + ring_name[i] = NULL; + } + } + RingDump(wifi_interface_handle iface, int id) + : WifiCommand("RingDump", iface, id), mLargestBuffSize(0), mBuff(NULL), + mErrCode(0) + { + } + + int start() { + DUMP_INFO(("Start Ring Dump Map_cnt:%d\n", mNumMaps)); + registerVendorHandler(GOOGLE_OUI, GOOGLE_FILE_DUMP_EVENT); + + //Set ringname to buf hashmap + for (int i = 0; i < mNumMaps; i++) { + int type = mMap[i].type; + ring_name[type] = (char *)malloc(DBGRING_NAME_MAX); + memset(ring_name[type], 0, DBGRING_NAME_MAX); + memcpy(ring_name[type], mMap[i].ring_name, strlen(mMap[i].ring_name)); + DUMP_DEBUG(("Set ringname Buf:%s Ringname:%s len:%lu", + EWP_CmdAttrToString(type), ring_name[type], strlen(mMap[i].ring_name))); + } + return WIFI_SUCCESS; + } + + virtual int freeup() { + DUMP_DEBUG(("freeup:Enter\n")); + if (mBuff) { + free(mBuff); + mBuff = NULL; + DUMP_INFO(("freed allocated memory\n")); + } + return WIFI_SUCCESS; + } + + virtual int cancel() { + /* unregister file dump handler */ + unregisterVendorHandler(GOOGLE_OUI, GOOGLE_FILE_DUMP_EVENT); + wifi_unregister_cmd(wifiHandle(), id()); + + /* Free up the ring names allocated */ + for (u8 i = 0; i < DUMP_BUF_ATTR_MAX; i++) { + if (ring_name[i]) { + free(ring_name[i]); + ring_name[i] = NULL; + } + } + if (mBuff) { + free(mBuff); + } + + DUMP_INFO(("Stop Ring Dump Successfully Completed, mErrCode = %d\n", mErrCode)); + return WIFI_SUCCESS; + } + + virtual int handleResponse(WifiEvent& reply) { + DUMP_DEBUG(("RingDump::handleResponse\n")); + int buf_attr = DUMP_BUF_ATTR_INVALID; + int len_attr = DUMP_LEN_ATTR_INVALID; + int index = -1; + + if (reply.get_cmd() != NL80211_CMD_VENDOR) { + ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); + return NL_SKIP; + } + + nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); + int len = reply.get_vendor_data_len(); + + if (vendor_data == NULL || len == 0) { + ALOGE("no vendor data in memory dump response; ignoring it"); + return NL_SKIP; + } + + for (nl_iterator it(vendor_data); it.has_next(); it.next()) { + buf_attr = it.get_type(); + switch (buf_attr) { + case DUMP_BUF_ATTR_MEMDUMP: + case DUMP_BUF_ATTR_TIMESTAMP: + case DUMP_BUF_ATTR_ECNTRS: + case DUMP_BUF_ATTR_DHD_DUMP: + case DUMP_BUF_ATTR_EXT_TRAP: + case DUMP_BUF_ATTR_HEALTH_CHK: + case DUMP_BUF_ATTR_COOKIE: + case DUMP_BUF_ATTR_FLOWRING_DUMP: + case DUMP_BUF_ATTR_STATUS_LOG: + case DUMP_BUF_ATTR_RTT_LOG: + case DUMP_BUF_ATTR_PKTID_MAP_LOG: + case DUMP_BUF_ATTR_PKTID_UNMAP_LOG: { + if (it.get_u32()) { + ALOGE("Copying data to userspace failed, status = %d\n", it.get_u32()); + return WIFI_ERROR_UNKNOWN; + } + index = logger_attr_buffer_lookup(buf_attr); + if (index == -1) { + ALOGE("Invalid index. buf attr = %s\n", EWP_CmdAttrToString(buf_attr)); + return WIFI_ERROR_UNKNOWN; + } + len_attr = attr_lookup_tbl[index].attr_type; + if (len_attr == DUMP_EVENT_ATTR_MAX) { + ALOGE("Invalid len attr = %s\n", EWP_EventAttrToString(len_attr)); + return WIFI_ERROR_UNKNOWN; + } + if (!mBuff || attr_type_len[len_attr] <= 0) { + return WIFI_ERROR_UNKNOWN; + } + + if (!ring_name[buf_attr]) { + ALOGE("Not allocated buf attr = %s\n", EWP_CmdAttrToString(buf_attr)); + return WIFI_ERROR_UNKNOWN; + } + DUMP_INFO(("RingDump:: buf_attr:%s size = %d ring_name:%s\n", + EWP_CmdAttrToString(buf_attr), attr_type_len[len_attr], + ring_name[buf_attr])); + if (mHandle.on_ring_buffer_data) { + /* on_ring_buffer_data callback requires status memory + * so should pass status memory */ + wifi_ring_buffer_status status; + memset(&status, 0, sizeof(status)); + /* Skip msg header. Retrieved log */ + (*mHandle.on_ring_buffer_data)(ring_name[buf_attr], mBuff, + attr_type_len[len_attr], &status); + } + if (mBuff) { + memset(mBuff, 0, mLargestBuffSize); + } + break; + } + default: { + DUMP_DEBUG(("Ignoring invalid attribute buf_attr = %d, size = %d", + buf_attr, it.get_len())); + break; + } + } + } + return NL_OK; + } + + virtual int request_logger_dump(WifiRequest& request, + buf_data_t *buf, int len_attr) { + + int result = 0; + int buf_attr = DUMP_BUF_ATTR_INVALID; + int index = -1; + nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); + + index = logger_attr_lookup(len_attr); + if (index == -1) { + ALOGE("Invalid index\n"); + return WIFI_ERROR_UNKNOWN; + } + buf_attr = attr_lookup_tbl[index].buf_attr; + + if (buf_attr != DUMP_BUF_ATTR_INVALID) { + result = request.put(buf_attr, buf, sizeof(buf_data_t)); + if (result != WIFI_SUCCESS) { + ALOGE("Failed to put get memory dump request; result = %d", result); + return result; + } + } else { + ALOGE("Invalid buf attr = %s, index = %d\n", + EWP_CmdAttrToString(buf_attr), index); + return WIFI_ERROR_UNKNOWN; + } + DUMP_INFO(("Trigger get dump for buf attr = %s\n", + EWP_CmdAttrToString(buf_attr))); + + request.attr_end(data); + return result; + } + + virtual int handleEvent(WifiEvent& event) { + mLargestBuffSize = 0; + mBuff = NULL; + memset(attr_type_len, 0, sizeof(attr_type_len)); + u8 i = 0; + int result = 0; + int mActualBuffSize = 0; + int index = -1; + + nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); + int len = event.get_vendor_data_len(); + int event_id = event.get_vendor_subcmd(); + int req_attr_cnt = 0; + int req_attr[DUMP_EVENT_ATTR_MAX]; + int buf_attr = DUMP_BUF_ATTR_INVALID; + + if (vendor_data == NULL || len == 0) { + ALOGE("No Debug data found"); + return NL_SKIP; + } + DUMP_INFO(("Ring Dump handler. Got event: %d", event_id)); + + buf_data_t buf; + + memset(&buf, 0, sizeof(buf_data_t)); + buf.ver = 0; + buf.buf_threshold = 0; + + if (event_id == GOOGLE_FILE_DUMP_EVENT) { + for (nl_iterator it(vendor_data); it.has_next(); it.next()) { + int attr = it.get_type(); + switch (attr) { + case DUMP_LEN_ATTR_MEMDUMP: + case DUMP_LEN_ATTR_TIMESTAMP: + case DUMP_LEN_ATTR_ECNTRS: + case DUMP_LEN_ATTR_DHD_DUMP: + case DUMP_LEN_ATTR_EXT_TRAP: + case DUMP_LEN_ATTR_HEALTH_CHK: + case DUMP_LEN_ATTR_COOKIE: + case DUMP_LEN_ATTR_FLOWRING_DUMP: + case DUMP_LEN_ATTR_STATUS_LOG: + case DUMP_LEN_ATTR_RTT_LOG: + case DUMP_LEN_ATTR_PKTID_MAP_LOG: + case DUMP_LEN_ATTR_PKTID_UNMAP_LOG: { + mActualBuffSize = it.get_u32(); + DUMP_DEBUG(("len attr %s, len %d\n", + EWP_EventAttrToString(attr), mActualBuffSize)); + if (mActualBuffSize > mLargestBuffSize) + mLargestBuffSize = mActualBuffSize; + attr_type_len[attr] = mActualBuffSize; + + /* Store the order in which attributes are received + * so that file dump can be done in the same order + */ + req_attr[req_attr_cnt++] = attr; + break; + } + default: { + ALOGE("Ignoring invalid attribute type = %d, size = %d", + attr, it.get_len()); + break; + } + } + } + /* Allocation for the largest buffer size to use it recursively for other buf attr. */ + if (mLargestBuffSize) { + DUMP_INFO(("Max dump size: %d", mLargestBuffSize)); + mBuff = (char *)malloc(mLargestBuffSize); + if (!mBuff) { + ALOGE("Buffer allocation failed"); + return NL_SKIP; + } + memset(mBuff, 0, mLargestBuffSize); + } + + WifiRequest request(familyId(), ifaceId()); + result = request.create(GOOGLE_OUI, LOGGER_DEBUG_GET_DUMP); + if (result != WIFI_SUCCESS) { + ALOGE("Failed to create get memory dump request; result = %d", result); + freeup(); + goto exit; + } + + /* Requesting logger dump for each received attr */ + for (i = 0; i < req_attr_cnt; i++) { + int attr = req_attr[i]; + + if (attr_type_len[attr] == 0) { + continue; + } + + index = logger_attr_lookup(attr); + buf_attr = attr_lookup_tbl[index].buf_attr; + if (!ring_name[buf_attr]) { + ALOGE("Failed to find ringname index:%d buf_attr:%d", index, buf_attr); + continue; + } + + buf.len = attr_type_len[attr]; + buf.data_buf[0] = mBuff; + DUMP_DEBUG(("buf len = %d, buf ptr= %p for attr = %s\n", + buf.len, buf.data_buf[0], EWP_EventAttrToString(attr))); + result = request_logger_dump(request, &buf, attr); + if (result != WIFI_SUCCESS) { + /* Proceeding further for other attributes */ + ALOGE("Failed to request the logger dump for attr = %s; result = %d", + EWP_EventAttrToString(attr), result); + continue; + } + result = requestResponse(request); + if (result != WIFI_SUCCESS) { + ALOGE("Failed to register get memory dump response for attr = %s; result = %d", + EWP_EventAttrToString(attr), result); + /* Proceeding further for other attributes */ + continue; + } + } + + WifiRequest request2(familyId(), ifaceId()); + result = request2.create(GOOGLE_OUI, LOGGER_FILE_DUMP_DONE_IND); + if (result != WIFI_SUCCESS) { + ALOGE("Failed to trigger dev close; result = %d", result); + freeup(); + goto exit; + } + requestResponse(request2); + freeup(); + } else { + ALOGE("dump event missing dump length attribute"); + return NL_SKIP; + } + exit: + if (result != WIFI_SUCCESS) { + return NL_SKIP; + } + return NL_OK; + } +}; +/////////////////////////////////////////////////////////////////////////////// +#endif /* RING_DUMP */ wifi_error wifi_start_hal(wifi_interface_handle iface) { @@ -1214,6 +1950,52 @@ wifi_error wifi_hal_preInit(wifi_interface_handle iface) return result; } +#ifdef RING_DUMP +wifi_error wifi_start_ring_dump(wifi_interface_handle iface, + wifi_ring_buffer_data_handler ring_handle) +{ + wifi_handle handle = getWifiHandle(iface); + DUMP_INFO(("start ring dump, handle = %p", handle)); + wifi_buf_ring_map_entry_t map[DUMP_BUF_ATTR_MAX]; + unsigned int num_maps = DUMP_BUF_ATTR_MAX; + wifi_error result; + + /* Get mapping table from driver */ + DebugCommand *debug_cmd = new DebugCommand(iface, &num_maps, map, GET_BUF_RING_MAP); + NULL_CHECK_RETURN(debug_cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + result = (wifi_error)debug_cmd->start(); + debug_cmd->releaseRef(); + + /* Set ringname to corresponding buf attr */ + RingDump *cmd = new RingDump(iface, FILE_DUMP_REQUEST_ID, num_maps, map, ring_handle); + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + result = wifi_register_cmd(handle, FILE_DUMP_REQUEST_ID, cmd); + if (result != WIFI_SUCCESS) { + cmd->releaseRef(); + return result; + } + + result = (wifi_error)cmd->start(); + if (result != WIFI_SUCCESS) { + wifi_unregister_cmd(handle, FILE_DUMP_REQUEST_ID); + cmd->releaseRef(); + return result; + } + return result; +} + +wifi_error wifi_stop_ring_dump(wifi_interface_handle iface, + wifi_ring_buffer_data_handler ring_handle) +{ + RingDump *cmd = new RingDump(iface, FILE_DUMP_REQUEST_ID); + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + DUMP_INFO(("stop ring dump")); + cmd->cancel(); + cmd->releaseRef(); + return WIFI_SUCCESS; +} +#endif /* RING_DUMP */ + wifi_error wifi_stop_hal(wifi_interface_handle iface) { HalInit *cmd = new HalInit(iface, HAL_START_REQUEST_ID); @@ -1809,11 +2591,10 @@ wifi_error wifi_get_wake_reason_stats(wifi_interface_handle handle, /////////////////////////////////////////////////////////////////////////////// class OtaUpdateCommand : public WifiCommand { - int mErrCode; public: OtaUpdateCommand(wifi_interface_handle iface) - : WifiCommand("OtaUpdateCommand", iface, 0), mErrCode(0) + : WifiCommand("OtaUpdateCommand", iface, 0) { } int start() { @@ -1935,7 +2716,7 @@ class OtaUpdateCommand : public WifiCommand wifi_error read_ota_file(char* file, char** buffer, uint32_t* size) { FILE* fp = NULL; - int file_size, count; + int file_size; char* buf; fp = fopen(file, "r"); @@ -1954,7 +2735,7 @@ wifi_error read_ota_file(char* file, char** buffer, uint32_t* size) } memset(buf, 0, file_size + 1); fseek(fp, 0, SEEK_SET); - count = fread(buf, file_size, 1, fp); + fread(buf, file_size, 1, fp); *buffer = (char*) buf; *size = file_size; diff --git a/bcmdhd/wifi_hal/wifi_offload.cpp b/bcmdhd/wifi_hal/wifi_offload.cpp index 1702ffd..a24a882 100644 --- a/bcmdhd/wifi_hal/wifi_offload.cpp +++ b/bcmdhd/wifi_hal/wifi_offload.cpp @@ -42,7 +42,7 @@ #include <log/log.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "cpp_bindings.h" |