Merge tag 'LA.VENDOR.1.0.r1-26900-WAIPIO.QSSI15.0' of https://git.codelinaro.org/clo/la/platform/hardware/qcom/wlan into android-15-caf
"LA.VENDOR.1.0.r1-26900-WAIPIO.QSSI15.0"
Change-Id: I0c2e57b3776647c1629b8cba6aa85a0b89f17d4e
diff --git a/.gitupstream b/.gitupstream
new file mode 100644
index 0000000..fe4ecc8
--- /dev/null
+++ b/.gitupstream
@@ -0,0 +1 @@
+https://git.codelinaro.org/clo/la/platform/hardware/qcom/wlan
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..9515b25
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,2 @@
+soong_namespace {
+}
diff --git a/Android.mk b/Android.mk
index 6695cef..3c542ca 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,6 +1,10 @@
+ifeq ($(call my-dir),$(call project-path-for,qcom-wlan))
+
# TODO: Find a better way to separate build configs for ADP vs non-ADP devices
QCOM_WLAN_ROOT := $(call my-dir)
ifneq ($(BOARD_IS_AUTOMOTIVE),true)
include $(call all-subdir-makefiles)
endif
+
+endif
diff --git a/cld80211-lib/Android.bp b/cld80211-lib/Android.bp
new file mode 100644
index 0000000..8879830
--- /dev/null
+++ b/cld80211-lib/Android.bp
@@ -0,0 +1,19 @@
+cc_library_headers {
+ name: "libcld80211_headers",
+ vendor: true,
+ export_include_dirs: ["."],
+}
+
+cc_library_shared {
+ name: "libcld80211",
+ vendor: true,
+
+ header_libs: ["libcld80211_headers"],
+ shared_libs: ["libcutils", "libnl", "liblog"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-parameter",
+ ],
+ srcs: ["cld80211_lib.c"],
+}
diff --git a/cld80211-lib/Android.mk b/cld80211-lib/Android.mk
deleted file mode 100644
index 404c116..0000000
--- a/cld80211-lib/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-# =================================
-# copy header
-# =================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libcld80211_headers
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_HEADER_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libcld80211
-LOCAL_CLANG := true
-LOCAL_MODULE_TAGS := optional
-LOCAL_C_INCLUDES += $(LOCAL_PATH) \
- external/libnl/include
-LOCAL_SHARED_LIBRARIES := libcutils libnl liblog
-LOCAL_SRC_FILES := cld80211_lib.c
-LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
-LOCAL_HEADER_LIBRARIES := libcld80211_headers
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/qcwcn/wifi_hal/Android.mk b/qcwcn/wifi_hal/Android.mk
index bd9eb2b..21e5016 100644
--- a/qcwcn/wifi_hal/Android.mk
+++ b/qcwcn/wifi_hal/Android.mk
@@ -38,7 +38,7 @@
include $(CLEAR_VARS)
LOCAL_CFLAGS := -Wno-unused-parameter
-ifeq ($(TARGET_BUILD_VARIANT),userdebug)
+ifeq ($(TARGET_BUILD_VARIANT),eng)
LOCAL_CFLAGS += "-DLOG_NDEBUG=0"
endif
@@ -46,6 +46,10 @@
LOCAL_CFLAGS += -DWCNSS_QTI_AOSP
endif
+ifeq ($(strip $(CONFIG_MAC_PRIVACY_LOGGING)),true)
+LOCAL_CFLAGS += -DCONFIG_MAC_PRIVACY_LOGGING
+endif
+
# gscan.cpp: address of array 'cached_results[i].results' will always evaluate to 'true'
LOCAL_CLANG_CFLAGS := -Wno-pointer-bool-conversion
@@ -62,6 +66,7 @@
$(LOCAL_PATH) \
external/libnl/include \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
+ hardware/interfaces/wifi/legacy_headers/include/hardware_legacy \
external/wpa_supplicant_8/src/drivers \
$(TARGET_OUT_HEADERS)/cld80211-lib
@@ -113,6 +118,10 @@
LOCAL_HEADER_LIBRARIES := libcutils_headers libutils_headers libwifi-hal-ctrl_headers libcld80211_headers
LOCAL_SANITIZE := cfi signed-integer-overflow unsigned-integer-overflow
+ifeq ($(TARGET_SUPPORTS_WEARABLES), true)
+LOCAL_CFLAGS += -DTARGET_SUPPORTS_WEARABLES
+endif
+
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
@@ -125,6 +134,10 @@
LOCAL_CFLAGS += "-DLOG_NDEBUG=0"
endif
+ifeq ($(strip $(CONFIG_MAC_PRIVACY_LOGGING)),true)
+LOCAL_CFLAGS += -DCONFIG_MAC_PRIVACY_LOGGING
+endif
+
# gscan.cpp: address of array 'cached_results[i].results' will always evaluate to 'true'
LOCAL_CLANG_CFLAGS := -Wno-pointer-bool-conversion
@@ -139,6 +152,7 @@
$(LOCAL_PATH) \
external/libnl/include \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
+ hardware/interfaces/wifi/legacy_headers/include/hardware_legacy \
external/wpa_supplicant_8/src/drivers \
$(TARGET_OUT_HEADERS)/cld80211-lib
@@ -192,4 +206,9 @@
LOCAL_HEADER_LIBRARIES := libcutils_headers libutils_headers libwifi-hal-ctrl_headers libcld80211_headers
LOCAL_SANITIZE := cfi integer_overflow
+
+ifeq ($(TARGET_SUPPORTS_WEARABLES), true)
+LOCAL_CFLAGS += -DTARGET_SUPPORTS_WEARABLES
+endif
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/qcwcn/wifi_hal/common.cpp b/qcwcn/wifi_hal/common.cpp
index 263043b..3bd78a6 100644
--- a/qcwcn/wifi_hal/common.cpp
+++ b/qcwcn/wifi_hal/common.cpp
@@ -18,8 +18,6 @@
#include <linux/pkt_sched.h>
#include <linux-private/linux/fib_rules.h>
#include <netlink/object-api.h>
-#include <netlink-private/object-api.h>
-#include <netlink-private/types.h>
#include <dlfcn.h>
#include <pthread.h>
#include "wifi_hal.h"
@@ -239,6 +237,7 @@
lowi_cb_table_t *LowiWifiHalApi = NULL;
/* LowiSupportedCapabilities read */
u32 lowiSupportedCapabilities = 0;
+bool lowiUnsupported = false;
int compareLowiVersion(u16 major, u16 minor, u16 micro)
{
@@ -269,21 +268,27 @@
*lowi_wifihal_api = NULL;
*lowi_get_capa_supported = false;
+ if (lowiUnsupported) {
+ return WIFI_ERROR_NOT_SUPPORTED;
+ }
+
#if __WORDSIZE == 64
void* lowi_handle = dlopen("/vendor/lib64/liblowi_wifihal.so", RTLD_NOW);
#else
void* lowi_handle = dlopen("/vendor/lib/liblowi_wifihal.so", RTLD_NOW);
#endif
if (!lowi_handle) {
- ALOGE("%s: NULL lowi_handle, err: %s", __FUNCTION__, dlerror());
- return WIFI_ERROR_UNKNOWN;
+ ALOGV("%s: NULL lowi_handle, err: %s", __FUNCTION__, dlerror());
+ retVal = WIFI_ERROR_NOT_SUPPORTED;
+ goto cleanup;
}
lowiCbTable = (getCbTable_t*)dlsym(lowi_handle,
"lowi_wifihal_get_cb_table");
if (!lowiCbTable) {
ALOGE("%s: NULL lowi callback table", __FUNCTION__);
- return WIFI_ERROR_UNKNOWN;
+ retVal = WIFI_ERROR_NOT_SUPPORTED;
+ goto cleanup;
}
*lowi_wifihal_api = lowiCbTable();
@@ -344,6 +349,7 @@
cleanup:
if (retVal) {
*lowi_wifihal_api = NULL;
+ lowiUnsupported = true;
}
return retVal;
}
@@ -353,6 +359,10 @@
int ret = WIFI_SUCCESS;
bool lowi_get_capabilities_support = false;
+ if (lowiUnsupported) {
+ return NULL;
+ }
+
if (LowiWifiHalApi == NULL) {
ALOGV("%s: LowiWifiHalApi Null, Initialize Lowi",
__FUNCTION__);
@@ -366,7 +376,7 @@
/* Initialize LOWI if it isn't up already. */
ret = LowiWifiHalApi->init();
if (ret) {
- ALOGE("%s: failed lowi initialization. "
+ ALOGW("%s: failed lowi initialization. "
"Returned error:%d. Exit.", __FUNCTION__, ret);
goto cleanup;
}
@@ -398,10 +408,12 @@
cleanup:
if (LowiWifiHalApi && LowiWifiHalApi->destroy) {
+ ALOGI("%s: Cleaning up Lowi due to failure. Return NULL", __FUNCTION__);
ret = LowiWifiHalApi->destroy();
}
LowiWifiHalApi = NULL;
lowiSupportedCapabilities = 0;
+ lowiUnsupported = true;
return LowiWifiHalApi;
}
diff --git a/qcwcn/wifi_hal/common.h b/qcwcn/wifi_hal/common.h
index 78ae269..9b1c347 100644
--- a/qcwcn/wifi_hal/common.h
+++ b/qcwcn/wifi_hal/common.h
@@ -91,6 +91,14 @@
#define WIFI_HAL_CTRL_IFACE "/dev/socket/wifihal/wifihal_ctrlsock"
+#ifdef CONFIG_MAC_PRIVACY_LOGGING
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[5]
+#define MACSTR "%02x:%02x:%02x:**:**:%02x"
+#else
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+#endif
+
#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
#ifndef BIT
@@ -213,6 +221,10 @@
bool apf_enabled;
bool support_nan_ext_cmd;
pkt_log_version pkt_log_ver;
+#ifndef TARGET_SUPPORTS_WEARABLES
+ /* Interface combination matrix */
+ wifi_iface_concurrency_matrix iface_comb_matrix;
+#endif /* TARGET_SUPPORTS_WEARABLES */
qca_wlan_vendor_sar_version sar_version;
} hal_info;
@@ -267,6 +279,10 @@
wifi_error wifi_get_radar_history(wifi_interface_handle handle,
radar_history_result *resultBuf, int resultBufSize, int *numResults);
wifi_error wifi_disable_next_cac(wifi_interface_handle handle);
+
+wifi_error wifi_get_supported_radio_combinations_matrix(
+ wifi_handle handle, u32 max_size, u32 *size,
+ wifi_radio_combination_matrix *radio_combination_matrix);
// some common macros
#define min(x, y) ((x) < (y) ? (x) : (y))
diff --git a/qcwcn/wifi_hal/gscan.cpp b/qcwcn/wifi_hal/gscan.cpp
index d1afee6..9350a34 100644
--- a/qcwcn/wifi_hal/gscan.cpp
+++ b/qcwcn/wifi_hal/gscan.cpp
@@ -1645,13 +1645,8 @@
cached_results[i].results[j].ts);
ALOGD("%s: SSID %s ", __FUNCTION__,
cached_results[i].results[j].ssid);
- ALOGD("%s: BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
- __FUNCTION__, cached_results[i].results[j].bssid[0],
- cached_results[i].results[j].bssid[1],
- cached_results[i].results[j].bssid[2],
- cached_results[i].results[j].bssid[3],
- cached_results[i].results[j].bssid[4],
- cached_results[i].results[j].bssid[5]);
+ ALOGD("%s: BSSID: " MACSTR " \n",
+ __FUNCTION__, MAC2STR(cached_results[i].results[j].bssid));
ALOGD("%s: channel %d ", __FUNCTION__,
cached_results[i].results[j].channel);
ALOGD("%s: rssi %d ", __FUNCTION__,
diff --git a/qcwcn/wifi_hal/gscan_event_handler.cpp b/qcwcn/wifi_hal/gscan_event_handler.cpp
index 074d64b..6639f8f 100644
--- a/qcwcn/wifi_hal/gscan_event_handler.cpp
+++ b/qcwcn/wifi_hal/gscan_event_handler.cpp
@@ -334,11 +334,9 @@
tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
ALOGV("gscan_parse_hotlist_ap_results: ts %" PRId64 " SSID %s "
- "BSSID: %02x:%02x:%02x:%02x:%02x:%02x channel %d rssi %d "
+ "BSSID: " MACSTR " channel %d rssi %d "
"rtt %" PRId64" rtt_sd %" PRId64,
- results[i].ts, results[i].ssid,
- results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
- results[i].bssid[3], results[i].bssid[4], results[i].bssid[5],
+ results[i].ts, results[i].ssid, MAC2STR(results[i].bssid),
results[i].channel, results[i].rssi, results[i].rtt,
results[i].rtt_sd);
/* Increment loop index for next record */
@@ -436,10 +434,8 @@
QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST]
), results[i]->num_rssi * sizeof(wifi_rssi));
- ALOGV("significant_change_result:%d, BSSID:"
- "%02x:%02x:%02x:%02x:%02x:%02x channel:%d num_rssi:%d ",
- i, results[i]->bssid[0], results[i]->bssid[1], results[i]->bssid[2],
- results[i]->bssid[3], results[i]->bssid[4], results[i]->bssid[5],
+ ALOGV("significant_change_result:%d, BSSID:" MACSTR " channel:%d num_rssi:%d ",
+ i, MAC2STR(results[i]->bssid),
results[i]->channel, results[i]->num_rssi);
rem_size = sizeof(rssi_buf);
@@ -577,11 +573,10 @@
tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
ALOGV("gscan_parse_hotlist_ssid_results: ts %" PRId64 " SSID %s "
- "BSSID: %02x:%02x:%02x:%02x:%02x:%02x channel %d rssi %d "
+ "BSSID: " MACSTR " channel %d rssi %d "
"rtt %" PRId64 " rtt_sd %" PRId64,
results[i].ts, results[i].ssid,
- results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
- results[i].bssid[3], results[i].bssid[4], results[i].bssid[5],
+ MAC2STR(results[i].bssid),
results[i].channel, results[i].rssi, results[i].rtt,
results[i].rtt_sd);
/* Increment loop index for next record */
@@ -731,16 +726,11 @@
mPasspointNetworkFoundResult->ie_length);
ALOGV("%s: ts: %" PRId64 " SSID: %s "
- "BSSID: %02x:%02x:%02x:%02x:%02x:%02x channel: %d rssi: %d"
+ "BSSID: " MACSTR " channel: %d rssi: %d"
" rtt: % " PRId64 " rtt_sd %" PRId64 " ie_length %u ",
__FUNCTION__, mPasspointNetworkFoundResult->ts,
mPasspointNetworkFoundResult->ssid,
- mPasspointNetworkFoundResult->bssid[0],
- mPasspointNetworkFoundResult->bssid[1],
- mPasspointNetworkFoundResult->bssid[2],
- mPasspointNetworkFoundResult->bssid[3],
- mPasspointNetworkFoundResult->bssid[4],
- mPasspointNetworkFoundResult->bssid[5],
+ MAC2STR(mPasspointNetworkFoundResult->bssid),
mPasspointNetworkFoundResult->channel,
mPasspointNetworkFoundResult->rssi,
mPasspointNetworkFoundResult->rtt,
@@ -931,11 +921,10 @@
QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]);
ALOGV("gscan_parse_pno_network_results: ts %" PRId64 " SSID %s "
- "BSSID: %02x:%02x:%02x:%02x:%02x:%02x channel %d rssi %d "
+ "BSSID: " MACSTR " channel %d rssi %d "
"rtt %" PRId64 " rtt_sd %" PRId64,
results[i].ts, results[i].ssid,
- results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
- results[i].bssid[3], results[i].bssid[4], results[i].bssid[5],
+ MAC2STR(results[i].bssid),
results[i].channel, results[i].rssi, results[i].rtt,
results[i].rtt_sd);
/* Increment loop index for next record */
@@ -1196,10 +1185,8 @@
#ifdef QC_HAL_DEBUG
ALOGD("handleEvent:FULL_SCAN_RESULTS: ts %" PRId64, result->ts);
ALOGD("handleEvent:FULL_SCAN_RESULTS: SSID %s ", result->ssid) ;
- ALOGD("handleEvent:FULL_SCAN_RESULTS: "
- "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
- result->bssid[0], result->bssid[1], result->bssid[2],
- result->bssid[3], result->bssid[4], result->bssid[5]);
+ ALOGD("handleEvent:FULL_SCAN_RESULTS: BSSID: " MACSTR " \n",
+ MAC2STR(result->bssid));
ALOGD("handleEvent:FULL_SCAN_RESULTS: channel %d ",
result->channel);
ALOGD("handleEvent:FULL_SCAN_RESULTS: rssi %d ", result->rssi);
diff --git a/qcwcn/wifi_hal/ifaceeventhandler.cpp b/qcwcn/wifi_hal/ifaceeventhandler.cpp
index 0c44e25..4f6271a 100644
--- a/qcwcn/wifi_hal/ifaceeventhandler.cpp
+++ b/qcwcn/wifi_hal/ifaceeventhandler.cpp
@@ -24,6 +24,40 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "sync.h"
@@ -169,6 +203,7 @@
mRequestId = id;
mSubcmd = subcmd;
registerHandler(mSubcmd);
+ memset(tb, 0, sizeof(struct nlattr *) * (NL80211_ATTR_MAX + 1));
ALOGV("wifiEventHandler %p constructed", this);
}
@@ -208,6 +243,9 @@
mfilter_packet_length = 0;
res_size = 0;
channel_buff = NULL;
+ mRadio_matrix = NULL;
+ mRadio_matrix_max_size = 0;
+ mRadio_matrix_size = NULL;
memset(&mDriverFeatures, 0, sizeof(mDriverFeatures));
memset(&mRadarResultParams, 0, sizeof(RadarHistoryResultsParams));
}
@@ -561,6 +599,11 @@
wifiParseRadarHistory();
}
break;
+ case QCA_NL80211_VENDOR_SUBCMD_GET_RADIO_COMBINATION_MATRIX:
+ {
+ wifi_parse_radio_combinations_matrix();
+ }
+ break;
case QCA_NL80211_VENDOR_SUBCMD_GET_SAR_CAPABILITY:
{
struct nlattr *tb_vendor[
@@ -568,7 +611,7 @@
nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_MAX,
(struct nlattr *)mVendorData,mDataLen, NULL);
- if (tb_vendor[QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION])
+ if(tb_vendor[QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION])
{
mInfo->sar_version = (qca_wlan_vendor_sar_version) nla_get_u32(tb_vendor[
QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION]);
@@ -700,6 +743,161 @@
return WIFI_SUCCESS;
}
+wifi_error WifihalGeneric::wifi_parse_radio_combinations_matrix() {
+ // tbVendor
+ struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_MAX + 1];
+ int rem = 0, rem_radio = 0;
+ u32 num_radio_combinations = 0, num_radio_configurations = 0;
+ // nested radio matrix configurations
+ struct nlattr *radio_combination[QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_MAX + 1];
+ struct nlattr *attr, *attr_cfg;
+ struct nlattr *radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_MAX + 1];
+ u8 band, antenna;
+ u32 result_size = sizeof(u32); /* num_radio_combinations */
+ bool max_size_exceeded = false;
+ u32 size_needed = 0, radio_cfg_size = 0;
+ bool invalid_radio_cfg = false;
+ wifi_radio_combination *radio_combination_ptr;
+ wifi_radio_configuration *radio_config;
+ u8 *buff_ptr;
+
+ static struct nla_policy
+ radio_combination_policy[QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_MAX + 1] = {
+ [QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_CFGS] = { .type = NLA_NESTED },
+ };
+
+ static struct nla_policy
+ radio_cfg_policy[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_MAX + 1] = {
+ [QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_BAND] = { .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_ANTENNA] = { .type = NLA_U8 },
+ };
+
+ if (nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_MAX,
+ (struct nlattr *)mVendorData,mDataLen, NULL)) {
+ ALOGE("%s: nla_parse ATTR_RADIO_MATRIX fail", __FUNCTION__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ if (!tbVendor[QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_SUPPORTED_CFGS]) {
+ ALOGE("%s: radio matrix attr entries not present", __FUNCTION__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ if (!mRadio_matrix) {
+ ALOGE("%s: radio matrix buffer is null", __FUNCTION__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ buff_ptr = (u8 *)mRadio_matrix;
+ buff_ptr += sizeof(u32); /* num_radio_combinations */
+ nla_for_each_nested(attr,
+ tbVendor[QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_SUPPORTED_CFGS],
+ rem) {
+ if (nla_parse_nested(radio_combination,
+ QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_MAX,
+ attr, radio_combination_policy)) {
+ ALOGI("%s: nla_parse_nested radio combination fail", __FUNCTION__);
+ continue;
+ }
+ radio_combination_ptr = (wifi_radio_combination *)buff_ptr;
+
+ num_radio_configurations = 0;
+ radio_cfg_size = 0;
+ nla_for_each_nested(attr_cfg,
+ radio_combination[QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_CFGS],
+ rem_radio) {
+ if (nla_parse_nested(radio_cfg,
+ QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_MAX,
+ attr_cfg, radio_cfg_policy)) {
+ ALOGI("%s: nla_parse_nested radio cfg attr fail", __FUNCTION__);
+ continue;
+ }
+
+ if (!radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_BAND] ||
+ !radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_ANTENNA]) {
+ ALOGI("%s: band/antenna info not present", __FUNCTION__);
+ continue;
+ }
+
+ if (!invalid_radio_cfg) {
+ if (!num_radio_configurations) {
+ size_needed = sizeof(wifi_radio_configuration) +
+ sizeof(u32);
+ buff_ptr += sizeof(u32); /* num_radio_configurations */
+ } else {
+ size_needed = sizeof(wifi_radio_configuration);
+ buff_ptr += sizeof(wifi_radio_configuration);
+ }
+ }
+ if (mRadio_matrix_max_size < result_size + size_needed) {
+ ALOGI("%s: Max size reached, max size %u, needed %u",
+ __FUNCTION__, mRadio_matrix_max_size,
+ result_size + size_needed);
+ max_size_exceeded = true;
+ break;
+ }
+ invalid_radio_cfg = false;
+ radio_config = (wifi_radio_configuration *)buff_ptr;
+
+ if (radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_BAND]) {
+ band = nla_get_u32(
+ radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_BAND]);
+ if (band == QCA_SETBAND_5G) {
+ radio_config->band = WLAN_MAC_5_0_BAND;
+ } else if (band == QCA_SETBAND_6G) {
+ radio_config->band = WLAN_MAC_6_0_BAND;
+ } else if (band == QCA_SETBAND_2G) {
+ radio_config->band = WLAN_MAC_2_4_BAND;
+ } else {
+ ALOGI("%s: Invalid band value %d", __FUNCTION__, band);
+ invalid_radio_cfg = true;
+ continue;
+ }
+ }
+ if (radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_ANTENNA]) {
+ antenna = nla_get_u8(
+ radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_ANTENNA]);
+ if (antenna == 1) {
+ radio_config->antenna_cfg = WIFI_ANTENNA_1X1;
+ } else if (antenna == 2) {
+ radio_config->antenna_cfg = WIFI_ANTENNA_2X2;
+ } else if (antenna == 3) {
+ radio_config->antenna_cfg = WIFI_ANTENNA_3X3;
+ } else if (antenna == 4) {
+ radio_config->antenna_cfg = WIFI_ANTENNA_4X4;
+ } else {
+ ALOGI("%s: Invalid antenna cfg value %d", __FUNCTION__,
+ antenna);
+ invalid_radio_cfg = true;
+ continue;
+ }
+ }
+ radio_cfg_size += size_needed;
+ num_radio_configurations++;
+ result_size += size_needed;
+ } /* RADIO_COMBINATIONS_CFGS */
+ if (num_radio_configurations) {
+ num_radio_combinations++;
+ radio_combination_ptr->num_radio_configurations =
+ num_radio_configurations;
+ ALOGI("%s: radio_combinations[%d]: num_radio_configurations %d",
+ __FUNCTION__, num_radio_combinations,
+ num_radio_configurations);
+ }
+
+ buff_ptr = (u8 *)radio_combination_ptr + radio_cfg_size;
+
+ if (max_size_exceeded)
+ break;
+ } /* RADIO_MATRIX_SUPPORTED_CFGS */
+ mRadio_matrix->num_radio_combinations = num_radio_combinations;
+ *mRadio_matrix_size = result_size;
+ ALOGI("%s: num_radio_combinations %d, radio_matrix_size %d", __FUNCTION__,
+ num_radio_combinations, result_size);
+
+ return WIFI_SUCCESS;
+}
+
wifi_error WifihalGeneric::wifiParseRadarHistory() {
{
// tbVendor
@@ -822,6 +1020,19 @@
mConcurrencySet = set;
}
+void WifihalGeneric::set_radio_matrix_max_size(u32 max_size) {
+ mRadio_matrix_max_size = max_size;
+}
+
+void WifihalGeneric::set_radio_matrix_size(u32 *size){
+ mRadio_matrix_size = size;
+}
+
+void WifihalGeneric::set_radio_matrix(
+ wifi_radio_combination_matrix *radio_combination_matrix){
+ mRadio_matrix = radio_combination_matrix;
+}
+
void WifihalGeneric::setSizePtr(int *set_size) {
mSetSizePtr = set_size;
}
@@ -929,6 +1140,8 @@
}
}
+
+
wifi_error WifihalGeneric::getSarVersion(wifi_interface_handle handle)
{
wifi_error ret;
@@ -956,3 +1169,4 @@
return ret;
}
+
diff --git a/qcwcn/wifi_hal/ifaceeventhandler.h b/qcwcn/wifi_hal/ifaceeventhandler.h
index eef9624..9e02105 100644
--- a/qcwcn/wifi_hal/ifaceeventhandler.h
+++ b/qcwcn/wifi_hal/ifaceeventhandler.h
@@ -24,6 +24,40 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __WIFI_HAL_IFACEEVENTHANDLER_COMMAND_H__
@@ -103,6 +137,10 @@
RadarHistoryResultsParams mRadarResultParams;
virtual wifi_error wifiParseCapabilities(struct nlattr **tbVendor);
virtual wifi_error wifiParseRadarHistory();
+ u32 mRadio_matrix_max_size;
+ u32 *mRadio_matrix_size;
+ wifi_radio_combination_matrix *mRadio_matrix;
+ virtual wifi_error wifi_parse_radio_combinations_matrix();
public:
WifihalGeneric(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
@@ -126,6 +164,9 @@
virtual wifi_error copyCachedRadarHistory(radar_history_result *resultBuf,
int resultBufSize, int *numResults);
virtual void freeCachedRadarHistory();
+ virtual void set_radio_matrix_max_size(u32 max_size);
+ virtual void set_radio_matrix_size(u32 *size);
+ virtual void set_radio_matrix(wifi_radio_combination_matrix *radio_combination_matrix);
virtual wifi_error getSarVersion(wifi_interface_handle handle);
};
diff --git a/qcwcn/wifi_hal/llstats.cpp b/qcwcn/wifi_hal/llstats.cpp
index 8fc8d77..86c372b 100644
--- a/qcwcn/wifi_hal/llstats.cpp
+++ b/qcwcn/wifi_hal/llstats.cpp
@@ -15,7 +15,7 @@
* Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
@@ -60,6 +60,7 @@
mRadioStatsSize = 0;
mNumRadios = 0;
mNumRadiosAllocated = 0;
+ mRequestId = 0;
}
LLStatsCommand::~LLStatsCommand()
@@ -966,7 +967,7 @@
{
if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS])
{
- ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS"
+ ALOGD("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS"
" not found", __FUNCTION__);
return WIFI_ERROR_INVALID_ARGS;
}
@@ -977,7 +978,7 @@
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS
])
{
- ALOGE("%s:"
+ ALOGD("%s:"
"QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS"
" not found", __FUNCTION__);
status = WIFI_ERROR_INVALID_ARGS;
@@ -1090,22 +1091,6 @@
{
goto cleanup;
}
-
- /* Driver/firmware might send this attribute when there
- * are no peers connected.
- * So that, the event
- * QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_PEERS can be
- * avoided.
- */
- if (tb_vendor[
- QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS])
- {
-#ifdef QC_HAL_DEBUG
- ALOGV("%s: numPeers is %u\n", __FUNCTION__,
- nla_get_u32(tb_vendor[
- QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]));
-#endif
- }
}
break;
diff --git a/qcwcn/wifi_hal/nan.cpp b/qcwcn/wifi_hal/nan.cpp
index 1690a86..a73126b 100644
--- a/qcwcn/wifi_hal/nan.cpp
+++ b/qcwcn/wifi_hal/nan.cpp
@@ -977,8 +977,8 @@
wifi_handle handle = getWifiHandle(iface);
hal_info *info = getHalInfo(handle);
- if (iface_name == NULL) {
- ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
+ if (iface_name == NULL || if_nametoindex(iface_name) == 0) {
+ ALOGE("%s: Invalid/Unknown Nan Data Interface Name. \n", __FUNCTION__);
return WIFI_ERROR_INVALID_ARGS;
}
@@ -988,11 +988,33 @@
return WIFI_ERROR_UNKNOWN;
}
+ // NL80211_CMD_DEL_INTERFACE internally takes care of NDP cleanup.
+ if ((check_feature(QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI,
+ &info->driver_supported_features)) &&
+ if_nametoindex(iface_name)) {
+ wifiConfigCommand = new WiFiConfigCommand(handle,
+ get_requestid(), 0, 0);
+ if (wifiConfigCommand == NULL) {
+ ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+ wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
+ wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
+ if_nametoindex(iface_name));
+ /* Send the NL msg. */
+ wifiConfigCommand->waitForRsp(false);
+ if (wifiConfigCommand->requestEvent() != WIFI_SUCCESS) {
+ ALOGE("%s: Delete intf failed", __FUNCTION__);
+ }
+ delete wifiConfigCommand;
+ return WIFI_SUCCESS;
+ }
+
ret = nan_initialize_vendor_cmd(iface,
&nanCommand);
if (ret != WIFI_SUCCESS) {
ALOGE("%s: Initialization failed", __FUNCTION__);
- goto delete_ndi;
+ return ret;
}
/* Add the vendor specific attributes for the NL command. */
@@ -1023,28 +1045,6 @@
cleanup:
delete nanCommand;
-
-delete_ndi:
- if ((check_feature(QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI,
- &info->driver_supported_features)) &&
- if_nametoindex(iface_name)) {
- wifiConfigCommand = new WiFiConfigCommand(handle,
- get_requestid(), 0, 0);
- if (wifiConfigCommand == NULL) {
- ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
- return WIFI_ERROR_UNKNOWN;
- }
- wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
- wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
- if_nametoindex(iface_name));
- /* Send the NL msg. */
- wifiConfigCommand->waitForRsp(false);
- if (wifiConfigCommand->requestEvent() != WIFI_SUCCESS) {
- ALOGE("%s: Delete intf failed", __FUNCTION__);
- }
- delete wifiConfigCommand;
- }
-
return ret;
}
diff --git a/qcwcn/wifi_hal/radio_mode.cpp b/qcwcn/wifi_hal/radio_mode.cpp
index 267d3f4..8cbbab2 100644
--- a/qcwcn/wifi_hal/radio_mode.cpp
+++ b/qcwcn/wifi_hal/radio_mode.cpp
@@ -27,8 +27,8 @@
* Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
- * SPDX-License-Identifier: BSD-3-Clause-Clear
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include "sync.h"
@@ -95,6 +95,7 @@
: WifiVendorCommand(handle, id, vendor_id, subcmd)
{
memset(&mHandler, 0, sizeof(mHandler));
+ mwifi_iface_mac_info = NULL;
if (registerVendorHandler(vendor_id, subcmd)) {
/* Error case should not happen print log */
ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
diff --git a/qcwcn/wifi_hal/roam.cpp b/qcwcn/wifi_hal/roam.cpp
index bd93c3d..ec2b290 100644
--- a/qcwcn/wifi_hal/roam.cpp
+++ b/qcwcn/wifi_hal/roam.cpp
@@ -80,10 +80,7 @@
}
for (i = 0; i < params.num_bssid; i++) {
- ALOGV("BSSID: %d : %02x:%02x:%02x:%02x:%02x:%02x", i,
- params.bssids[i][0], params.bssids[i][1],
- params.bssids[i][2], params.bssids[i][3],
- params.bssids[i][4], params.bssids[i][5]);
+ ALOGV("BSSID: %d : " MACSTR, i, MAC2STR(params.bssids[i]));
}
roamCommand =
diff --git a/qcwcn/wifi_hal/tdls.cpp b/qcwcn/wifi_hal/tdls.cpp
index c54928f..54555e2 100644
--- a/qcwcn/wifi_hal/tdls.cpp
+++ b/qcwcn/wifi_hal/tdls.cpp
@@ -27,7 +27,7 @@
* Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
@@ -51,6 +51,7 @@
memset(&mHandler, 0, sizeof(mHandler));
memset(&mTDLSgetStatusRspParams, 0, sizeof(wifi_tdls_status));
mRequestId = 0;
+ memset(&mTDLSgetCaps, 0, sizeof(wifiTdlsCapabilities));
}
TdlsCommand::~TdlsCommand()
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp
index a6fa064..5de5ac8 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/qcwcn/wifi_hal/wifi_hal.cpp
@@ -64,8 +64,12 @@
#include <netlink/object-api.h>
#include <netlink/netlink.h>
#include <netlink/socket.h>
+#if __has_include(<netlink-private/types.h>)
#include <netlink-private/object-api.h>
#include <netlink-private/types.h>
+#else
+#include <nl-priv-dynamic-core/nl-core.h>
+#endif
#include "nl80211_copy.h"
@@ -90,6 +94,7 @@
#include "wifiloggercmd.h"
#include "tcp_params_update.h"
+
/*
BUGBUG: normally, libnl allocates ports for all connections it makes; but
being a static library, it doesn't really know how many other netlink
@@ -147,6 +152,13 @@
wifi_init_tcp_param_change_event_handler(wifi_interface_handle iface);
wifi_error wifi_set_voip_mode(wifi_interface_handle iface, wifi_voip_mode mode);
+#ifndef TARGET_SUPPORTS_WEARABLES
+wifi_error wifi_get_supported_iface_combination(wifi_interface_handle iface_handle);
+
+wifi_error wifi_get_supported_iface_concurrency_matrix(
+ wifi_handle handle,
+ wifi_iface_concurrency_matrix *iface_concurrency_matrix);
+#endif /* TARGET_SUPPORTS_WEARABLES */
/* Initialize/Cleanup */
@@ -439,6 +451,7 @@
return ret;
}
+
static wifi_error get_firmware_bus_max_size_supported(
wifi_interface_handle iface)
{
@@ -1120,6 +1133,12 @@
fn->wifi_set_dtim_config = wifi_set_dtim_config;
fn->wifi_set_voip_mode = wifi_set_voip_mode;
fn->wifi_get_usable_channels = wifi_get_usable_channels;
+ fn->wifi_get_supported_radio_combinations_matrix =
+ wifi_get_supported_radio_combinations_matrix;
+#ifndef TARGET_SUPPORTS_WEARABLES
+ fn->wifi_get_supported_iface_concurrency_matrix =
+ wifi_get_supported_iface_concurrency_matrix;
+#endif /* TARGET_SUPPORTS_WEARABLES */
return WIFI_SUCCESS;
}
@@ -1451,6 +1470,14 @@
ALOGV("support_nan_ext_cmd is %d",
info->support_nan_ext_cmd);
+#ifndef TARGET_SUPPORTS_WEARABLES
+ ret = wifi_get_supported_iface_combination(iface_handle);
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("Failed to get driver supported interface combinations");
+ goto unload;
+ }
+#endif /* TARGET_SUPPORTS_WEARABLES */
+
ret = wifi_get_sar_version(iface_handle);
if (ret != WIFI_SUCCESS) {
ALOGE("Failed to get SAR Version, Setting it to default.");
@@ -2584,6 +2611,73 @@
return ret;
}
+wifi_error wifi_get_supported_radio_combinations_matrix(
+ wifi_handle handle, u32 max_size, u32 *size,
+ wifi_radio_combination_matrix *radio_combination_matrix)
+{
+ wifi_error ret = WIFI_ERROR_UNKNOWN;;
+ struct nlattr *nlData;
+ WifihalGeneric *vCommand = NULL;
+ hal_info *info = NULL;
+
+ ALOGI("%s: enter", __FUNCTION__);
+ if (!handle) {
+ ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ info = getHalInfo(handle);
+ if (!info || info->num_interfaces < 1) {
+ ALOGE("%s: Error, wifi_handle NULL or base wlan interface not present",
+ __FUNCTION__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ if (size == NULL || radio_combination_matrix == NULL) {
+ ALOGE("%s: NULL set pointer provided. Exit.",
+ __func__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ if (max_size < sizeof(u32)) {
+ ALOGE("%s: Invalid max size value %d", __func__, max_size);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ vCommand = new WifihalGeneric(handle, get_requestid(), OUI_QCA,
+ QCA_NL80211_VENDOR_SUBCMD_GET_RADIO_COMBINATION_MATRIX);
+ if (vCommand == NULL) {
+ ALOGE("%s: Error vCommand NULL", __FUNCTION__);
+ return WIFI_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = vCommand->create();
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+ if (!nlData){
+ ret = WIFI_ERROR_UNKNOWN;
+ goto cleanup;
+ }
+
+ vCommand->attr_end(nlData);
+
+ /* Populate the input received from caller/framework. */
+ vCommand->set_radio_matrix_max_size(max_size);
+ vCommand->set_radio_matrix_size(size);
+ vCommand->set_radio_matrix(radio_combination_matrix);
+
+ ret = vCommand->requestResponse();
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: requestResponse() error: %d", __FUNCTION__, ret);
+ goto cleanup;
+ }
+
+cleanup:
+ delete vCommand;
+ return ret;
+}
wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs)
{
@@ -3344,6 +3438,330 @@
}
}
+#ifndef TARGET_SUPPORTS_WEARABLES
+char *get_iface_mask_str(u32 mask, char *buf, size_t buflen) {
+ char * pos, *end;
+ int res;
+
+ pos = buf;
+ end = buf + buflen;
+
+ res = snprintf(pos, end - pos, "[ ");
+ if (res < 0 || (res >= end - pos))
+ goto error;
+
+ pos += res;
+ res = snprintf(pos, end - pos, "%s", (mask & BIT(WIFI_INTERFACE_TYPE_STA)) ? "STA " : "");
+ if (res < 0 || (res >= end - pos))
+ goto error;
+
+ pos += res;
+ res = snprintf(pos, end - pos, "%s", (mask & BIT(WIFI_INTERFACE_TYPE_AP)) ? "AP " : "");
+ if (res < 0 || (res >= end - pos))
+ goto error;
+
+ pos += res;
+ res = snprintf(pos, end - pos, "%s", (mask & BIT(WIFI_INTERFACE_TYPE_P2P)) ? "P2P " : "");
+ if (res < 0 || (res >= end - pos))
+ goto error;
+
+ pos += res;
+ res = snprintf(pos, end - pos, "%s", (mask & BIT(WIFI_INTERFACE_TYPE_NAN)) ? "NAN " : "");
+ if (res < 0 || (res >= end - pos))
+ goto error;
+
+ pos += res;
+ res = snprintf(pos, end - pos, "%s", (mask & BIT(WIFI_INTERFACE_TYPE_AP_BRIDGED)) ? "AP_BRIDGED " : "");
+ if (res < 0 || (res >= end - pos))
+ goto error;
+
+ pos += res;
+ res = snprintf(pos, end - pos, "]");
+ if (res < 0 || (res >= end - pos))
+ goto error;
+
+ return buf;
+
+error:
+ ALOGE("snprintf() error res=%d, write length=%d", res, static_cast<int>(end - pos));
+ return NULL;
+}
+
+static void dump_wifi_iface_combination(wifi_iface_concurrency_matrix *matrix) {
+
+ u32 i, j;
+ wifi_iface_combination *comb;
+ wifi_iface_limit *limit;
+ char buf[30];
+
+ if (matrix == NULL) return;
+
+ ALOGV("--- DUMP Interface Combination ---");
+ ALOGV("num_iface_combinations: %u", matrix->num_iface_combinations);
+ for (i = 0; i < matrix->num_iface_combinations; i++) {
+ comb = &matrix->iface_combinations[i];
+ ALOGV("comb%d : max_ifaces: %u iface_limit: %u", i+1, comb->max_ifaces, comb->num_iface_limits);
+ for (j = 0; j < comb->num_iface_limits; j++) {
+ limit = &comb->iface_limits[j];
+ ALOGV(" max=%u, iface:%s", limit->max_limit, get_iface_mask_str(limit->iface_mask, buf, 30) ? buf : "");
+ }
+ }
+}
+
+
+class GetSupportedIfaceCombinationCmd : public WifiCommand
+{
+private:
+ hal_info *halinfo;
+
+public:
+ GetSupportedIfaceCombinationCmd(wifi_handle handle,
+ hal_info *info)
+ : WifiCommand(handle, 0),
+ halinfo(info) {}
+
+ virtual wifi_error create() {
+ int nl80211_id = genl_ctrl_resolve(mInfo->cmd_sock, "nl80211");
+ wifi_error ret = mMsg.create(nl80211_id, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, 0);
+ mMsg.put_flag(NL80211_ATTR_SPLIT_WIPHY_DUMP);
+
+ return ret;
+ }
+
+ virtual wifi_error requestResponse() {
+ return WifiCommand::requestResponse(mMsg);
+ }
+ virtual wifi_error set_iface_id(const char* name) {
+ unsigned ifindex = if_nametoindex(name);
+ return mMsg.set_iface_id(ifindex);
+ }
+
+ /**
+ * Derive the bridge combinations by adding the bridge interface when combination
+ * has support for more than one AP interface
+ */
+ void derive_bridge_ap_support(wifi_iface_concurrency_matrix* matrix)
+ {
+ if (matrix == NULL)
+ return;
+
+ int i, j, k, num_bridge, rem_ap;
+ int num_bridge_combination = 0;
+ wifi_iface_combination *comb;
+ wifi_iface_limit *limit;
+
+ // Add Support for bridge interface
+ for (i = 0; i < matrix->num_iface_combinations; i++) {
+ comb = &matrix->iface_combinations[i];
+
+ /* find out if this combination has support for AP > 1 */
+ bool bridge_ap_supported = false;
+ for (j = 0; j < comb->num_iface_limits; j++) {
+ limit = &comb->iface_limits[j];
+ if ((limit->iface_mask & BIT(WIFI_INTERFACE_TYPE_AP))
+ && (limit->max_limit > 1)) {
+ bridge_ap_supported = true;
+ break;
+ }
+ }
+ if (bridge_ap_supported) {
+ /* Bridge combination is a new combination along with other type of ifaces */
+ num_bridge_combination++;
+ k = matrix->num_iface_combinations + num_bridge_combination;
+ if (k == MAX_IFACE_COMBINATIONS) {
+ ALOGE("max iface combination %u limit reached. Stop processing further", k);
+ break;
+ }
+
+ wifi_iface_combination *comb_br = &matrix->iface_combinations[k-1];
+ num_bridge = 0;
+
+ for (j = 0, k = 0; (j < comb->num_iface_limits) && (k < MAX_IFACE_LIMITS); j++, k++) {
+ limit = &comb->iface_limits[j];
+ /* count the possible number of bridge interface based on max_limit/2
+ * Also maintain remaining interfaces as AP */
+ if ((limit->iface_mask & BIT(WIFI_INTERFACE_TYPE_AP))
+ && (limit->max_limit > 1)) {
+ num_bridge = limit->max_limit / 2;
+ rem_ap = limit->max_limit % 2;
+ if (rem_ap) {
+ comb_br->iface_limits[k].max_limit = rem_ap;
+ comb_br->iface_limits[k].iface_mask = BIT(WIFI_INTERFACE_TYPE_AP);
+ k++;
+ }
+ if (k < MAX_IFACE_LIMITS) {
+ comb_br->iface_limits[k].iface_mask = BIT(WIFI_INTERFACE_TYPE_AP_BRIDGED);
+ comb_br->iface_limits[k].max_limit = num_bridge;
+ } else {
+ ALOGE("Can't add more than %d iface limits."
+ " Skip adding bridged mode", MAX_IFACE_LIMITS);
+ break;
+ }
+ } else {
+ // Retain other ifaces in this combination as is
+ comb_br->iface_limits[k].iface_mask = limit->iface_mask;
+ comb_br->iface_limits[k].max_limit = limit->max_limit;
+ }
+ }
+ // Reduce max ifaces which are converted to bridge iface.
+ comb_br->max_ifaces = comb->max_ifaces - num_bridge;
+ comb_br->num_iface_limits = k;
+ }
+ }
+ matrix->num_iface_combinations += num_bridge_combination;
+ }
+
+ virtual int handleResponse(WifiEvent& reply) {
+ struct nlattr **tb = reply.attributes();
+
+ if (tb[NL80211_ATTR_INTERFACE_COMBINATIONS]) {
+ if (halinfo == NULL) {
+ ALOGE("hal_info is NULL. Abort parsing");
+ return NL_SKIP;
+ }
+
+ wifi_iface_concurrency_matrix* matrix = &halinfo->iface_comb_matrix;
+ wifi_iface_combination *iface_combination;
+ wifi_iface_limit *iface_limits;
+ struct nlattr *nl_combi;
+ int rem, i = 0;
+
+ matrix->num_iface_combinations = 0;
+
+ nla_for_each_nested(nl_combi, tb[NL80211_ATTR_INTERFACE_COMBINATIONS], rem) {
+ struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
+ struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
+ struct nlattr *nl_limit, *nl_mode;
+ int err, rem_limit, rem_mode, j = 0;
+ static struct nla_policy
+ iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
+ [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
+ [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
+ [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
+ [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
+ [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
+ },
+ iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
+ [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
+ [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
+ };
+
+ err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
+ nl_combi, iface_combination_policy);
+ if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
+ !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
+ !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
+ ALOGE("Broken iface combination detected. skip it");
+ continue; /* broken combination */
+ }
+
+ iface_combination = &matrix->iface_combinations[i];
+ iface_combination->max_ifaces = nla_get_u32(tb_comb[NL80211_IFACE_COMB_MAXNUM]);
+ iface_limits = iface_combination->iface_limits;
+ nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS],
+ rem_limit) {
+ if (j == MAX_IFACE_LIMITS) {
+ ALOGE("Can't parse more than %d iface limits", MAX_IFACE_LIMITS);
+ continue;
+ }
+
+ err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
+ nl_limit, iface_limit_policy);
+ if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES]) {
+ ALOGE("Broken iface limt types detected. skip it");
+ continue; /* broken combination */
+ }
+
+ iface_limits[j].iface_mask = 0;
+ iface_limits[j].max_limit = nla_get_u32(tb_limit[NL80211_IFACE_LIMIT_MAX]);
+ bool is_p2p_go = false, is_p2p_client = false;
+ nla_for_each_nested(nl_mode,
+ tb_limit[NL80211_IFACE_LIMIT_TYPES],
+ rem_mode) {
+ int ift = nla_type(nl_mode);
+ switch (ift) {
+ case NL80211_IFTYPE_STATION:
+ iface_limits[j].iface_mask |= BIT(WIFI_INTERFACE_TYPE_STA);
+ break;
+ case NL80211_IFTYPE_P2P_GO:
+ is_p2p_go = true;
+ iface_limits[j].iface_mask |= BIT(WIFI_INTERFACE_TYPE_P2P);
+ break;
+ case NL80211_IFTYPE_P2P_CLIENT:
+ is_p2p_client = true;
+ iface_limits[j].iface_mask |= BIT(WIFI_INTERFACE_TYPE_P2P);
+ break;
+ case NL80211_IFTYPE_AP:
+ iface_limits[j].iface_mask |= BIT(WIFI_INTERFACE_TYPE_AP);
+ break;
+ case NL80211_IFTYPE_NAN:
+ iface_limits[j].iface_mask |= BIT(WIFI_INTERFACE_TYPE_NAN);
+ break;
+ case NL80211_IFTYPE_P2P_DEVICE:
+ ALOGI("Ignore p2p_device iface type");
+ iface_limits[j].max_limit--;
+ break;
+ default:
+ ALOGI("Ignore unsupported iface type: %d", ift);
+ break;
+ }
+ }
+ // Remove P2P if both client/Go are not set.
+ if ((iface_limits[j].iface_mask & BIT(WIFI_INTERFACE_TYPE_P2P))
+ && (!is_p2p_client || !is_p2p_go))
+ iface_limits[j].iface_mask &= ~BIT(WIFI_INTERFACE_TYPE_P2P);
+
+ // Ignore Unsupported Ifaces (ex Monitor interface)
+ if (iface_limits[j].iface_mask)
+ j++;
+ }
+ iface_combination->num_iface_limits = j;
+ i++;
+ if (i == MAX_IFACE_COMBINATIONS) {
+ ALOGE("%s max iface combination %u limit reached. Stop processing further", __func__, i);
+ break;
+ }
+ }
+ matrix->num_iface_combinations = i;
+ derive_bridge_ap_support(matrix);
+ }
+ return NL_SKIP;
+ }
+};
+
+wifi_error wifi_get_supported_iface_combination(wifi_interface_handle iface_handle)
+{
+ wifi_error ret;
+ wifi_handle handle = getWifiHandle(iface_handle);
+ hal_info *info = (hal_info *) handle;
+ interface_info *iface_info = getIfaceInfo(iface_handle);
+
+ GetSupportedIfaceCombinationCmd cmd(handle, info);
+
+ ret = cmd.create();
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: create command failed", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = cmd.set_iface_id(iface_info->name);
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: set iface id failed", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = cmd.requestResponse();
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("Failed to query supported iface combination, ret=%d", ret);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ dump_wifi_iface_combination(&info->iface_comb_matrix);
+
+ return ret;
+}
+#endif /* TARGET_SUPPORTS_WEARABLES */
+
wifi_error wifi_get_radar_history(wifi_interface_handle handle,
radar_history_result *resultBuf, int resultBufSize, int *numResults)
{
@@ -3514,3 +3932,40 @@
delete vCommand;
return ret;
}
+
+#ifndef TARGET_SUPPORTS_WEARABLES
+wifi_error wifi_get_supported_iface_concurrency_matrix(
+ wifi_handle handle, wifi_iface_concurrency_matrix *iface_comb_matrix)
+{
+ wifi_error ret = WIFI_ERROR_UNKNOWN;
+ hal_info *info = (hal_info *) handle;
+ wifi_iface_combination *comb;
+ wifi_iface_limit *limit;
+
+ if (info == NULL) {
+ ALOGE("Wifi not initialized yet.");
+ return ret;
+ }
+
+ if (iface_comb_matrix == NULL) {
+ ALOGE("Interface combination matrix not initialized.");
+ return ret;
+ }
+
+ ALOGI("Get supported concurrency capabilities");
+ // Copy over from info to input param.
+ iface_comb_matrix->num_iface_combinations =
+ info->iface_comb_matrix.num_iface_combinations;
+ for (int i = 0; i < iface_comb_matrix->num_iface_combinations; i++) {
+ comb = &iface_comb_matrix->iface_combinations[i];
+ comb->max_ifaces = info->iface_comb_matrix.iface_combinations[i].max_ifaces;
+ comb->num_iface_limits = info->iface_comb_matrix.iface_combinations[i].num_iface_limits;
+ for (int j = 0; j < comb->num_iface_limits; j++) {
+ limit = &comb->iface_limits[j];
+ limit->max_limit = info->iface_comb_matrix.iface_combinations[i].iface_limits[j].max_limit;
+ limit->iface_mask = info->iface_comb_matrix.iface_combinations[i].iface_limits[j].iface_mask;
+ }
+ }
+ return WIFI_SUCCESS;
+}
+#endif /* TARGET_SUPPORTS_WEARABLES */
diff --git a/qcwcn/wifi_hal/wificonfig.cpp b/qcwcn/wifi_hal/wificonfig.cpp
index 288a2cf..f5cbddd 100644
--- a/qcwcn/wifi_hal/wificonfig.cpp
+++ b/qcwcn/wifi_hal/wificonfig.cpp
@@ -24,11 +24,41 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+ *
* Changes from Qualcomm Innovation Center are provided under the following license:
-
+ *
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "sync.h"
@@ -48,9 +78,12 @@
#include "wificonfigcommand.h"
#include "ifaceeventhandler.h"
+
#define NUM_OF_SAR_LIMITS_SPECS 2
#define NUM_OF_SPEC_CHAINS 2
+
+
/* Implementation of the API functions exposed in wifi_config.h */
wifi_error wifi_extended_dtim_config_set(wifi_request_id id,
wifi_interface_handle iface,
@@ -561,6 +594,7 @@
return ret;
}
+
wifi_error wifi_select_SARv01_tx_power_scenario(wifi_interface_handle handle,
wifi_power_scenario scenario)
{
@@ -750,7 +784,7 @@
nlSpecList = wifiConfigCommand->attr_start(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC);
- if (!nlSpecList)
+ if(!nlSpecList)
{
ALOGE("Cannot create spec list");
ret = WIFI_ERROR_UNKNOWN;
@@ -760,11 +794,11 @@
for (int i = 0; i < NUM_OF_SPEC_CHAINS; i++) {
nlSpec = wifiConfigCommand->attr_start(0);
- if (!nlSpec) {
+ if(!nlSpec) {
ret = WIFI_ERROR_UNKNOWN;
goto cleanup;
}
- if (wifiConfigCommand->put_u32(
+ if(wifiConfigCommand->put_u32(
QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN,
i))
{
@@ -773,7 +807,7 @@
goto cleanup;
}
- if (wifiConfigCommand->put_u32(
+ if(wifiConfigCommand->put_u32(
QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX,
power_lim_idx))
{
@@ -820,8 +854,8 @@
info->sar_version == QCA_WLAN_VENDOR_SAR_VERSION_3)
return wifi_select_SARv02_tx_power_scenario(handle,scenario);
else {
- ALOGE("wifi_select_tx_power_scenario %u invalid or not supported", (u32)info->sar_version);
- return WIFI_ERROR_UNKNOWN;
+ ALOGE("wifi_select_tx_power_scenario %u invalid or not supported", (u32)info->sar_version);
+ return WIFI_ERROR_UNKNOWN;
}
}
@@ -1702,7 +1736,7 @@
}
if (wifiConfigCommand->put_u8(QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE,
- (mode==WIFI_VOIP_MODE_ON) ? 1 : 0)) {
+ (mode==WIFI_VOIP_MODE_VOICE) ? 1 : 0)) {
ALOGE("%s: failed to put vendor data", __FUNCTION__);
ret = WIFI_ERROR_UNKNOWN;
goto cleanup;
diff --git a/qcwcn/wifi_hal/wifihal_vendor.cpp b/qcwcn/wifi_hal/wifihal_vendor.cpp
index 4837e63..e05e407 100644
--- a/qcwcn/wifi_hal/wifihal_vendor.cpp
+++ b/qcwcn/wifi_hal/wifihal_vendor.cpp
@@ -28,7 +28,7 @@
* Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
@@ -74,6 +74,7 @@
memset(&mStats, 0,sizeof(nud_stats));
mpktInfo = NULL;
mnumStats = 0;
+ memset(&mHandler, 0, sizeof(pkt_stats_result_handler));
}
NUDStatsCommand::~NUDStatsCommand()
diff --git a/qcwcn/wifi_hal/wifilogger.cpp b/qcwcn/wifi_hal/wifilogger.cpp
index 384633a..a7cb0ab 100644
--- a/qcwcn/wifi_hal/wifilogger.cpp
+++ b/qcwcn/wifi_hal/wifilogger.cpp
@@ -27,7 +27,7 @@
*
* Changes from Qualcomm Innovation Center are provided under the following license:
*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the
@@ -840,6 +840,7 @@
mWaitforRsp = false;
mMoreData = false;
mSupportedSet = NULL;
+ mGetWakeStats = NULL;
}
WifiLoggerCommand::~WifiLoggerCommand()
diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/qcwcn/wifi_hal/wifilogger_diag.cpp
index f026a78..96202c4 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.cpp
+++ b/qcwcn/wifi_hal/wifilogger_diag.cpp
@@ -1317,7 +1317,7 @@
push_out_all_ring_buffers(info);
if (lfd_event->is_fatal == WLAN_LOG_TYPE_FATAL) {
- ALOGE("Received fatal event, sending alert");
+ ALOGE("Received log complete event, sending alert");
send_alert(info, lfd_event->reason_code);
}
}
@@ -2240,6 +2240,13 @@
info->pkt_fate_stats->n_tx_stats_collected];
pkt_fate_stats->fate = (wifi_tx_packet_fate)log->status;
+
+ if (pkt_fate_stats->fate > TX_PKT_FATE_DRV_DROP_OTHER) {
+ ALOGE("Invalid Tx pkt fate status %d, set to drv_drop_other",
+ pkt_fate_stats->fate);
+ pkt_fate_stats->fate = TX_PKT_FATE_DRV_DROP_OTHER;
+ }
+
if (log->type == TX_MGMT_PKT)
pkt_fate_stats->frame_inf.payload_type = FRAME_TYPE_80211_MGMT;
else
@@ -2774,7 +2781,7 @@
if (!info->cldctx) {
if ((wnl->nlh.nlmsg_len <= sizeof(tAniNlHdr)) ||
(wnl->nlh.nlmsg_len < (sizeof(tAniNlHdr) + ntohs(wnl->clh.wmsg.length)))) {
- ALOGE("Received UMAC message with insufficent length: %d",
+ ALOGV("Received UMAC message with insufficent length: %d",
wnl->nlh.nlmsg_len);
return WIFI_ERROR_UNKNOWN;
}
diff --git a/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
index b4f7606..397f0c7 100644
--- a/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
+++ b/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c
@@ -164,6 +164,9 @@
#define AP_AC_VALUE_STR_LEN strlen(AP_AC_VALUE_STR)
#define MAC_ADDR_STR_LEN strlen(MAC_ADDRESS_STR)
+// Module defined MAC ADDR macros to print full mac address.
+// This is in order to remove dependency from MAC2STR definitions
+// in common.h from wpa_supplicant.
#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
@@ -1225,7 +1228,6 @@
}
ext_id = *ie++;
- ie_len--;
switch (ext_id) {
case WLAN_EID_EXT_HE_CAPABILITIES:
@@ -2675,7 +2677,6 @@
TWT_SET_PARAM_STR_LEN) == 0) {
return QCA_WLAN_TWT_SET_PARAM;
} else {
- wpa_printf(MSG_DEBUG, "Not a TWT command");
return TWT_CMD_NOT_EXIST;
}
}
@@ -3045,7 +3046,6 @@
get_u32_from_string(cmd, &ret);
if (ret < 0)
return ret;
- cmd = move_to_next_str(cmd);
}
print_setup_cmd_values(twt_setup_params);
@@ -5673,7 +5673,7 @@
return NL_SKIP;
}
ret = os_snprintf(info->reply_buf, info->reply_buf_len,
- "tsf_value:%llu host_time:%llu", tsf_value, host_time);
+ "tsf_value:%lul host_time:%lul", tsf_value, host_time);
if (os_snprintf_error(info->reply_buf_len, ret)) {
wpa_printf(MSG_ERROR, "%s:Fail to print buffer", __func__);
return -ENOMEM;
@@ -6626,7 +6626,7 @@
ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
if (!ret)
ret = os_snprintf(buf, buf_len,
- "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
+ "Macaddr = " MAC_ADDR_STR "\n", MAC_ADDR_ARRAY(macaddr));
} else if (os_strncasecmp(cmd, "SET_CONGESTION_REPORT ", 22) == 0) {
return wpa_driver_cmd_set_congestion_report(priv, cmd + 22);
} else if (os_strncasecmp(cmd, "SET_TXPOWER ", 12) == 0) {
diff --git a/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c b/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c
index 6b611a1..8799326 100644
--- a/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c
+++ b/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c
@@ -77,9 +77,11 @@
void wpa_msg_handler(struct wpa_driver_nl80211_data *drv,
char *msg, u32 subcmd)
{
- if ((subcmd == QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
- (subcmd == QCA_NL80211_VENDOR_SUBCMD_OEM_DATA) ||
- (subcmd == QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET)) {
+ if (subcmd == QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT ||
+ subcmd == QCA_NL80211_VENDOR_SUBCMD_OEM_DATA ||
+ subcmd == QCA_NL80211_VENDOR_SUBCMD_SR ||
+ subcmd == QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET ||
+ subcmd == QCA_NL80211_VENDOR_SUBCMD_CONNECTED_CHANNEL_STATS) {
wpa_msg(drv->ctx, MSG_INFO, "%s", msg);
}
}
diff --git a/wcnss-service/Android.mk b/wcnss-service/Android.mk
index fd33ee1..9eab85b 100644
--- a/wcnss-service/Android.mk
+++ b/wcnss-service/Android.mk
@@ -9,7 +9,15 @@
LOCAL_SRC_FILES := wcnss_service.c
LOCAL_SHARED_LIBRARIES := libc libcutils libutils liblog
ifeq ($(strip $(TARGET_USES_QCOM_WCNSS_QMI)),true)
-LOCAL_CFLAGS += -DWCNSS_QMI
+ifeq ($(TARGET_USES_WCNSS_MAC_ADDR_REV),true)
+LOCAL_CFLAGS += -DWCNSS_QMI_MAC_ADDR_REV
+endif
+ifeq ($(TARGET_PROVIDES_WCNSS_QMI),true)
+LOCAL_CFLAGS += -DWCNSS_QMI_OSS
+LOCAL_SHARED_LIBRARIES += libdl
+else
+LOCAL_CFLAGS += -DWCNSS_QMI -DMDM_DETECT
+LOCAL_HEADER_LIBRARIES += libmdmdetect_headers
ifeq ($(filter 10% Q% q%,$(TARGET_PLATFORM_VERSION)),)
#For Android R and above, assuming not compiling on Q and lower
LOCAL_HEADER_LIBRARIES += libqmi_common_headers
@@ -21,6 +29,7 @@
LOCAL_HEADER_LIBRARIES += libmdmdetect_headers
LOCAL_SHARED_LIBRARIES += libmdmdetect
LOCAL_HEADER_LIBRARIES += libril-qc-qmi-services-headers
+endif #TARGET_PROVIDES_WCNSS_QMI
endif #TARGET_USES_QCOM_WCNSS_QMI
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS += -Wall -Werror
diff --git a/wcnss-service/wcnss_service.c b/wcnss-service/wcnss_service.c
index c817be1..70f9970 100644
--- a/wcnss-service/wcnss_service.c
+++ b/wcnss-service/wcnss_service.c
@@ -37,13 +37,19 @@
#include <utime.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
+#include <unistd.h>
#define LOG_TAG "wcnss_service"
#include <cutils/log.h>
#include <cutils/properties.h>
#ifdef WCNSS_QMI
#include "wcnss_qmi_client.h"
+#ifdef MDM_DETECT
#include "mdm_detect.h"
#endif
+#endif
+#ifdef WCNSS_QMI_OSS
+#include <dlfcn.h>
+#endif
#define SUCCESS 0
#define FAILED -1
@@ -72,7 +78,6 @@
#define WLAN_INI_FILE_SOURCE "/vendor/etc/wifi/WCNSS_qcom_cfg.ini"
#define WCNSS_HAS_CAL_DATA\
"/sys/module/wcnsscore/parameters/has_calibrated_data"
-#define WLAN_DRIVER_ATH_DEFAULT_VAL "0"
#define ASCII_A 65
#define ASCII_a 97
@@ -80,7 +85,7 @@
#define HEXA_A 10
#define HEX_BASE 16
-#ifdef WCNSS_QMI
+#if defined (WCNSS_QMI) || defined(WCNSS_QMI_OSS)
#define WLAN_ADDR_SIZE 6
unsigned char wlan_nv_mac_addr[WLAN_ADDR_SIZE];
#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
@@ -389,17 +394,15 @@
}
-#ifdef WCNSS_QMI
+#if defined(WCNSS_QMI) || defined(WCNSS_QMI_OSS)
void setup_wcnss_parameters(int *cal, int nv_mac_addr)
#else
void setup_wcnss_parameters(int *cal)
#endif
{
char msg[WCNSS_MAX_CMD_LEN];
- char serial[PROPERTY_VALUE_MAX];
int fd, rc, pos = 0;
struct stat st;
- unsigned int serial_num = 0;
fd = open(WCNSS_CTRL, O_WRONLY);
if (fd < 0) {
@@ -407,26 +410,7 @@
return;
}
- rc = property_get("ro.serialno", serial, "");
- if (rc) {
- serial_num = convert_string_to_hex(serial);
- ALOGE("Serial Number is %x", serial_num);
-
- msg[pos++] = WCNSS_USR_SERIAL_NUM >> BYTE_1;
- msg[pos++] = WCNSS_USR_SERIAL_NUM >> BYTE_0;
- msg[pos++] = serial_num >> BYTE_3;
- msg[pos++] = serial_num >> BYTE_2;
- msg[pos++] = serial_num >> BYTE_1;
- msg[pos++] = serial_num >> BYTE_0;
-
- if (write(fd, msg, pos) < 0) {
- ALOGE("Failed to write to %s : %s", WCNSS_CTRL,
- strerror(errno));
- goto fail;
- }
- }
-
-#ifdef WCNSS_QMI
+#if defined(WCNSS_QMI) || defined (WCNSS_QMI_OSS)
if (SUCCESS == nv_mac_addr)
{
pos = 0;
@@ -493,12 +477,7 @@
return;
}
-void setup_wlan_driver_ath_prop()
-{
- property_set("vendor.wlan.driver.ath", WLAN_DRIVER_ATH_DEFAULT_VAL);
-}
-
-#ifdef WCNSS_QMI
+#ifdef MDM_DETECT
int check_modem_compatability(struct dev_info *mdm_detect_info)
{
char args[MODEM_BASEBAND_PROPERTY_SIZE] = {0};
@@ -720,20 +699,99 @@
}
+#ifdef WCNSS_QMI_OSS
+static void *wcnss_qmi_handle = NULL;
+static int (*wcnss_init_qmi)(void) = NULL;
+static int (*wcnss_qmi_get_wlan_address)(unsigned char *) = NULL;
+static void (*wcnss_qmi_deinit)(void) = NULL;
+
+static int setup_wcnss_qmi(void)
+{
+ const char *error = NULL;
+
+ /* initialize the DMS client and request the wlan mac address */
+ wcnss_qmi_handle = dlopen("libwcnss_qmi.so", RTLD_NOW);
+ if (!wcnss_qmi_handle) {
+ ALOGE("Failed to open libwcnss_qmi.so: %s", dlerror());
+ goto dlopen_err;
+ }
+
+ dlerror();
+
+ wcnss_init_qmi = dlsym(wcnss_qmi_handle, "wcnss_init_qmi");
+ if ((error = dlerror()) != NULL) {
+ ALOGE("Failed to resolve function: %s: %s",
+ "wcnss_init_qmi", error);
+ goto dlsym_err;
+ }
+
+ dlerror();
+
+ wcnss_qmi_get_wlan_address = dlsym(wcnss_qmi_handle,
+ "wcnss_qmi_get_wlan_address");
+ if ((error = dlerror()) != NULL) {
+ ALOGE("Failed to resolve function: %s: %s",
+ "wcnss_qmi_get_wlan_address", error);
+ goto dlsym_err;
+ }
+
+ dlerror();
+
+ wcnss_qmi_deinit = dlsym(wcnss_qmi_handle, "wcnss_qmi_deinit");
+ if ((error = dlerror()) != NULL) {
+ ALOGE("Failed to resolve function: %s: %s",
+ "wcnss_qmi_deinit", error);
+ goto dlsym_err;
+ }
+
+ return SUCCESS;
+
+dlsym_err:
+ dlclose(wcnss_qmi_handle);
+dlopen_err:
+ return FAILED;
+}
+#endif
+
int main(int argc, char *argv[])
{
UNUSED(argc), UNUSED(argv);
int rc;
int fd_dev, ret_cal;
-#ifdef WCNSS_QMI
+#if defined(WCNSS_QMI) || defined(WCNSS_QMI_OSS)
int nv_mac_addr = FAILED;
+#ifdef MDM_DETECT
struct dev_info mdm_detect_info;
int nom = 0;
#endif
+#endif
setup_wlan_config_file();
+#ifdef WCNSS_QMI_OSS
+ /* dlopen WCNSS QMI lib */
+
+ rc = setup_wcnss_qmi();
+ if (rc == SUCCESS) {
+ if (SUCCESS == (*wcnss_init_qmi)()) {
+ rc = (*wcnss_qmi_get_wlan_address)(wlan_nv_mac_addr);
+ if (rc == SUCCESS) {
+ nv_mac_addr = SUCCESS;
+ ALOGE("WLAN MAC Addr:" MAC_ADDRESS_STR,
+ MAC_ADDR_ARRAY(wlan_nv_mac_addr));
+ } else
+ ALOGE("Failed to Get MAC addr from modem");
+
+ (*wcnss_qmi_deinit)();
+ }
+ else
+ ALOGE("Failed to Initialize wcnss QMI Interface");
+ } else {
+ ALOGE("Failed to Initialize wcnss QMI interface library");
+ }
+#endif
#ifdef WCNSS_QMI
+#ifdef MDM_DETECT
/* Call ESOC API to get the number of modems.
If the number of modems is not zero, only then proceed
with the eap_proxy intialization.*/
@@ -755,6 +813,7 @@
ALOGE("wcnss_service: Target does not have external modem");
goto nomodem;
}
+#endif
/* initialize the DMS client and request the wlan mac address */
@@ -779,7 +838,7 @@
dynamic_nv_replace();
-#ifdef WCNSS_QMI
+#if defined(WCNSS_QMI) || defined(WCNSS_QMI_OSS)
setup_wcnss_parameters(&ret_cal, nv_mac_addr);
#else
setup_wcnss_parameters(&ret_cal);
@@ -800,8 +859,6 @@
ALOGE("Cal data is successfully written to WCNSS");
}
- setup_wlan_driver_ath_prop();
-
rc = wcnss_read_and_store_cal_data(fd_dev);
if (rc != SUCCESS)
ALOGE("Failed to read and save cal data %d", rc);
@@ -811,5 +868,9 @@
close(fd_dev);
+#ifdef WCNSS_QMI_OSS
+ dlclose(wcnss_qmi_handle);
+#endif
+
return rc;
}