Wifi: Add support to query and use driver advertised interface combination
Interface combinations in legacy-hal is predefined with
'WIFI_HAL_INTERFACE_COMBINATIONS' build flag. This change
allows the WiFi HAL to request all the possible interface
concurrency combinations via vendor HAL API,
wifi_get_supported_iface_concurrency_matrix(). Thus build time
dependency can be removed by querying the combination at runtime.
Bug: 249351396
Change-Id: I3bc85ac013490949aab71a00f60028bf5daee68c
Merged-In: I3bc85ac013490949aab71a00f60028bf5daee68c
Test: Build successfully
Signed-off-by: Purushottam Kushwaha <quic_pkushwah@quicinc.com>
(cherry picked from commit f68b9a270973151b7f78882db383d81c0c5a9145)
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index efd6598..d3cf7bf 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -3300,6 +3300,64 @@
return channel_category_mask;
}
+bool convertLegacyIfaceMaskToIfaceConcurrencyType(u32 mask,
+ std::vector<IfaceConcurrencyType>* types) {
+ if (!mask) return false;
+
+#ifndef BIT
+#define BIT(x) (1 << (x))
+#endif
+ if (mask & BIT(WIFI_INTERFACE_TYPE_STA)) types->push_back(IfaceConcurrencyType::STA);
+ if (mask & BIT(WIFI_INTERFACE_TYPE_AP)) types->push_back(IfaceConcurrencyType::AP);
+ if (mask & BIT(WIFI_INTERFACE_TYPE_AP_BRIDGED))
+ types->push_back(IfaceConcurrencyType::AP_BRIDGED);
+ if (mask & BIT(WIFI_INTERFACE_TYPE_P2P)) types->push_back(IfaceConcurrencyType::P2P);
+ if (mask & BIT(WIFI_INTERFACE_TYPE_NAN)) types->push_back(IfaceConcurrencyType::NAN_IFACE);
+
+ return true;
+}
+
+bool convertLegacyIfaceCombinationsMatrixToChipMode(
+ legacy_hal::wifi_iface_concurrency_matrix& legacy_matrix, IWifiChip::ChipMode* chip_mode) {
+ if (!chip_mode) {
+ LOG(ERROR) << "chip_mode is null";
+ return false;
+ }
+ *chip_mode = {};
+
+ int num_combinations = legacy_matrix.num_iface_combinations;
+ std::vector<IWifiChip::ChipConcurrencyCombination> driver_Combinations_vec;
+ if (!num_combinations) {
+ LOG(ERROR) << "zero iface combinations";
+ return false;
+ }
+
+ for (int i = 0; i < num_combinations; i++) {
+ IWifiChip::ChipConcurrencyCombination chipComb;
+ std::vector<IWifiChip::ChipConcurrencyCombinationLimit> limits;
+ wifi_iface_combination* comb = &legacy_matrix.iface_combinations[i];
+ if (!comb->num_iface_limits) continue;
+ for (u32 j = 0; j < comb->num_iface_limits; j++) {
+ IWifiChip::ChipConcurrencyCombinationLimit chipLimit;
+ chipLimit.maxIfaces = comb->iface_limits[j].max_limit;
+ std::vector<IfaceConcurrencyType> types;
+ if (!convertLegacyIfaceMaskToIfaceConcurrencyType(comb->iface_limits[j].iface_mask,
+ &types)) {
+ LOG(ERROR) << "Failed to convert from iface_mask:"
+ << comb->iface_limits[j].iface_mask;
+ return false;
+ }
+ chipLimit.types = types;
+ limits.push_back(chipLimit);
+ }
+ chipComb.limits = limits;
+ driver_Combinations_vec.push_back(chipComb);
+ }
+
+ chip_mode->availableCombinations = driver_Combinations_vec;
+ return true;
+}
+
} // namespace aidl_struct_util
} // namespace wifi
} // namespace hardware
diff --git a/wifi/aidl/default/aidl_struct_util.h b/wifi/aidl/default/aidl_struct_util.h
index 904ba81..208b734 100644
--- a/wifi/aidl/default/aidl_struct_util.h
+++ b/wifi/aidl/default/aidl_struct_util.h
@@ -67,6 +67,8 @@
WifiRadioCombinationMatrix* aidl_matrix);
WifiBand convertLegacyMacBandToAidlWifiBand(uint32_t band);
WifiAntennaMode convertLegacyAntennaConfigurationToAidl(uint32_t antenna_cfg);
+bool convertLegacyIfaceCombinationsMatrixToChipMode(
+ legacy_hal::wifi_iface_concurrency_matrix& legacy_matrix, IWifiChip::ChipMode* chip_mode);
// STA iface conversion methods.
bool convertLegacyFeaturesToAidlStaCapabilities(uint64_t legacy_feature_set, uint32_t* aidl_caps);
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
index b4c2ccd..bb3eaf0 100644
--- a/wifi/aidl/default/wifi_chip.cpp
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -377,6 +377,35 @@
debug_ring_buffer_cb_registered_(false),
subsystemCallbackHandler_(handler) {
setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
+ using_dynamic_iface_combination_ = false;
+}
+
+void WifiChip::retrieveDynamicIfaceCombination() {
+ if (using_dynamic_iface_combination_) return;
+
+ legacy_hal::wifi_iface_concurrency_matrix legacy_matrix;
+ legacy_hal::wifi_error legacy_status;
+
+ std::tie(legacy_status, legacy_matrix) =
+ legacy_hal_.lock()->getSupportedIfaceConcurrencyMatrix();
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get SupportedIfaceCombinations matrix from legacy HAL: "
+ << legacyErrorToString(legacy_status);
+ return;
+ }
+
+ IWifiChip::ChipMode aidl_chip_mode;
+ if (!aidl_struct_util::convertLegacyIfaceCombinationsMatrixToChipMode(legacy_matrix,
+ &aidl_chip_mode)) {
+ LOG(ERROR) << "Failed convertLegacyIfaceCombinationsMatrixToChipMode() ";
+ return;
+ }
+
+ LOG(INFO) << "Reloading iface concurrency combination from driver";
+ aidl_chip_mode.id = feature_flags::chip_mode_ids::kV3;
+ modes_.clear();
+ modes_.push_back(aidl_chip_mode);
+ using_dynamic_iface_combination_ = true;
}
std::shared_ptr<WifiChip> WifiChip::create(
@@ -1509,6 +1538,8 @@
version_info.first.firmwareDescription.c_str());
property_set("vendor.wlan.driver.version", version_info.first.driverDescription.c_str());
}
+ // Get the driver supported interface combination.
+ retrieveDynamicIfaceCombination();
return ndk::ScopedAStatus::ok();
}
diff --git a/wifi/aidl/default/wifi_chip.h b/wifi/aidl/default/wifi_chip.h
index ff4ee9c..def5da0 100644
--- a/wifi/aidl/default/wifi_chip.h
+++ b/wifi/aidl/default/wifi_chip.h
@@ -262,6 +262,7 @@
getSupportedRadioCombinationsMatrixInternal();
std::pair<WifiChipCapabilities, ndk::ScopedAStatus> getWifiChipCapabilitiesInternal();
ndk::ScopedAStatus setMloModeInternal(const ChipMloMode in_mode);
+ void retrieveDynamicIfaceCombination();
void setWeakPtr(std::weak_ptr<WifiChip> ptr);
int32_t chip_id_;
@@ -283,6 +284,7 @@
// registration mechanism. Use this to check if we have already
// registered a callback.
bool debug_ring_buffer_cb_registered_;
+ bool using_dynamic_iface_combination_;
aidl_callback_util::AidlCallbackHandler<IWifiChipEventCallback> event_cb_handler_;
std::weak_ptr<WifiChip> weak_ptr_this_;
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
index dbf5a68..209670b 100644
--- a/wifi/aidl/default/wifi_legacy_hal.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -1885,6 +1885,14 @@
return global_func_table_.wifi_set_mlo_mode(global_handle_, mode);
}
+std::pair<wifi_error, wifi_iface_concurrency_matrix>
+WifiLegacyHal::getSupportedIfaceConcurrencyMatrix() {
+ wifi_iface_concurrency_matrix iface_concurrency_matrix;
+ wifi_error status = global_func_table_.wifi_get_supported_iface_concurrency_matrix(
+ global_handle_, &iface_concurrency_matrix);
+ return {status, iface_concurrency_matrix};
+}
+
void WifiLegacyHal::invalidate() {
global_handle_ = nullptr;
iface_name_to_handle_.clear();
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
index 1d59b17..5168a8b 100644
--- a/wifi/aidl/default/wifi_legacy_hal.h
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -290,6 +290,7 @@
using ::WIFI_ERROR_UNKNOWN;
using ::wifi_gscan_capabilities;
using ::wifi_hal_fn;
+using ::wifi_iface_concurrency_matrix;
using ::WIFI_INDOOR_CHANNEL;
using ::wifi_information_element;
using ::WIFI_INTERFACE_IBSS;
@@ -779,6 +780,7 @@
std::pair<wifi_error, wifi_chip_capabilities> getWifiChipCapabilities();
wifi_error enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag);
wifi_error setMloMode(wifi_mlo_mode mode);
+ std::pair<wifi_error, wifi_iface_concurrency_matrix> getSupportedIfaceConcurrencyMatrix();
private:
// Retrieve interface handles for all the available interfaces.
diff --git a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
index 77d1cb5..b5196c9 100644
--- a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
@@ -178,6 +178,7 @@
populateStubFor(&hal_fn->wifi_nan_resume_request);
populateStubFor(&hal_fn->wifi_set_scan_mode);
populateStubFor(&hal_fn->wifi_set_mlo_mode);
+ populateStubFor(&hal_fn->wifi_get_supported_iface_concurrency_matrix);
return true;
}