Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef97d23f authored by Sunil Ravi's avatar Sunil Ravi
Browse files

wifi: Get the supported radio combinations matrix

Added API to get the supported radio combinations
of the chip. This is mainly to check if the chip is
capable of multi band simultaneous operation.

For Example in case of a chip which has two radios, where one radio is
capable of 2.4GHz 2X2 only and another radio which is capable of either
5GHz or 6GHz 2X2, number of possible radio combinations in this case
are 5 and possible combinations are:
    {{{2G 2X2}}, //Standalone 2G
    {{5G 2X2}}, //Standalone 5G
    {{6G 2X2}}, //Standalone 6G
    {{2G 2X2}, {5G 2X2}}, //2G+5G DBS
    {{2G 2X2}, {6G 2X2}}} //2G+6G DBS

Bug: 208877624
Test: vts test
Change-Id: I4c90f80002ca138133a575bca80dfdef2a593ab2
parent 1aab61da
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -99,4 +99,35 @@ interface IWifiChip extends @1.5::IWifiChip {
    getUsableChannels_1_6(WifiBand band, bitfield<WifiIfaceMode> ifaceModeMask,
        bitfield<UsableChannelFilter> filterMask)
        generates (WifiStatus status, vec<WifiUsableChannel> channels);

    /**
     * Retrieve the list of all the possible radio combinations supported by this
     * chip.
     *
     * @return status WifiStatus of the operation.
     *         Possible status codes:
     *         |WifiStatusCode.SUCCESS|,
     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
     *         |WifiStatusCode.FAILURE_UNKNOWN|
     * @return radioCombinationMatrix
     *         A list of all the possible radio combinations represented by
     *         |WifiRadioCombinationMatrix|.
     *         For Example in case of a chip which has two radios, where one radio is
     *         capable of 2.4GHz 2X2 only and another radio which is capable of either
     *         5GHz or 6GHz 2X2, number of possible radio combinations in this case
     *         are 5 and possible combinations are
     *         {{{2G 2X2}}, //Standalone 2G
     *         {{5G 2X2}}, //Standalone 5G
     *         {{6G 2X2}}, //Standalone 6G
     *         {{2G 2X2}, {5G 2X2}}, //2G+5G DBS
     *         {{2G 2X2}, {6G 2X2}}} //2G+6G DBS
     *         Note: Since this chip doesn’t support 5G+6G simultaneous operation
     *         as there is only one radio which can support both bands, So it can only
     *         do MCC 5G+6G. This table should not get populated with possible MCC
     *         configurations. This is only for simultaneous radio configurations
     *         (such as standalone, multi band simultaneous or single band simultaneous).
     */
    getSupportedRadioCombinationsMatrix()
        generates (WifiStatus status, WifiRadioCombinationMatrix radioCombinationMatrix);
};
+94 −0
Original line number Diff line number Diff line
@@ -367,6 +367,21 @@ uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand hidl_band) {
    }
}

V1_5::WifiBand convertLegacyMacBandToHidlWifiBand(uint32_t band) {
    switch (band) {
        case legacy_hal::WLAN_MAC_2_4_BAND:
            return V1_5::WifiBand::BAND_24GHZ;
        case legacy_hal::WLAN_MAC_5_0_BAND:
            return V1_5::WifiBand::BAND_5GHZ;
        case legacy_hal::WLAN_MAC_6_0_BAND:
            return V1_5::WifiBand::BAND_6GHZ;
        case legacy_hal::WLAN_MAC_60_0_BAND:
            return V1_5::WifiBand::BAND_60GHZ;
        default:
            return V1_5::WifiBand::BAND_UNSPECIFIED;
    }
}

uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask) {
    uint32_t legacy_iface_mask = 0;
    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_STA) {
@@ -2905,6 +2920,85 @@ bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
    return true;
}

V1_6::WifiAntennaMode convertLegacyAntennaConfigurationToHidl(uint32_t antenna_cfg) {
    switch (antenna_cfg) {
        case legacy_hal::WIFI_ANTENNA_1X1:
            return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_1X1;
        case legacy_hal::WIFI_ANTENNA_2X2:
            return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_2X2;
        case legacy_hal::WIFI_ANTENNA_3X3:
            return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_3X3;
        case legacy_hal::WIFI_ANTENNA_4X4:
            return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_4X4;
        default:
            return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_UNSPECIFIED;
    }
}

bool convertLegacyWifiRadioConfigurationToHidl(
        legacy_hal::wifi_radio_configuration* radio_configuration,
        V1_6::WifiRadioConfiguration* hidl_radio_configuration) {
    if (!hidl_radio_configuration) {
        return false;
    }
    *hidl_radio_configuration = {};
    hidl_radio_configuration->bandInfo =
            hidl_struct_util::convertLegacyMacBandToHidlWifiBand(radio_configuration->band);
    if (hidl_radio_configuration->bandInfo == V1_5::WifiBand::BAND_UNSPECIFIED) {
        LOG(ERROR) << "Unspecified band";
        return false;
    }
    hidl_radio_configuration->antennaMode =
            hidl_struct_util::convertLegacyAntennaConfigurationToHidl(
                    radio_configuration->antenna_cfg);
    return true;
}

bool convertLegacyRadioCombinationsMatrixToHidl(
        legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
        WifiRadioCombinationMatrix* hidl_matrix) {
    if (!hidl_matrix || !legacy_matrix) {
        return false;
    }
    *hidl_matrix = {};

    int num_combinations = legacy_matrix->num_radio_combinations;
    std::vector<V1_6::WifiRadioCombination> radio_combinations_vec;
    if (!num_combinations) {
        LOG(ERROR) << "zero radio combinations";
        return false;
    }
    wifi_radio_combination* l_radio_combinations_ptr = legacy_matrix->radio_combinations;
    for (int i = 0; i < num_combinations; i++) {
        int num_configurations = l_radio_combinations_ptr->num_radio_configurations;
        WifiRadioCombination radioCombination;
        std::vector<V1_6::WifiRadioConfiguration> radio_configurations_vec;
        if (!num_configurations) {
            LOG(ERROR) << "zero radio configurations";
            return false;
        }
        for (int j = 0; j < num_configurations; j++) {
            WifiRadioConfiguration radioConfiguration;
            wifi_radio_configuration* l_radio_configurations_ptr =
                    &l_radio_combinations_ptr->radio_configurations[j];
            if (!hidl_struct_util::convertLegacyWifiRadioConfigurationToHidl(
                        l_radio_configurations_ptr, &radioConfiguration)) {
                LOG(ERROR) << "Error converting wifi radio configuration";
                return false;
            }
            radio_configurations_vec.push_back(radioConfiguration);
        }
        radioCombination.radioConfigurations = radio_configurations_vec;
        radio_combinations_vec.push_back(radioCombination);
        l_radio_combinations_ptr =
                (wifi_radio_combination*)((u8*)l_radio_combinations_ptr +
                                          sizeof(wifi_radio_combination) +
                                          (sizeof(wifi_radio_configuration) * num_configurations));
    }
    hidl_matrix->radioCombinations = radio_combinations_vec;
    return true;
}

}  // namespace hidl_struct_util
}  // namespace implementation
}  // namespace V1_6
+5 −0
Original line number Diff line number Diff line
@@ -74,6 +74,11 @@ bool convertHidlCoexUnsafeChannelToLegacy(
bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
        const std::vector<V1_5::IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
        std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels);
bool convertLegacyRadioCombinationsMatrixToHidl(
        legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
        V1_6::WifiRadioCombinationMatrix* hidl_matrix);
V1_5::WifiBand convertLegacyMacBandToHidlWifiBand(uint32_t band);
V1_6::WifiAntennaMode convertLegacyAntennaConfigurationToHidl(uint32_t antenna_cfg);

// STA iface conversion methods.
bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set,
+102 −0
Original line number Diff line number Diff line
@@ -377,6 +377,108 @@ TEST_F(HidlStructUtilTest, CanConvertLegacyFeaturesToHidl) {
                      HidlChipCaps::SET_LATENCY_MODE | HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP,
              hidle_caps);
}

void insertRadioCombination(legacy_hal::wifi_radio_combination* dst_radio_combination_ptr,
                            int num_radio_configurations,
                            legacy_hal::wifi_radio_configuration* radio_configuration) {
    dst_radio_combination_ptr->num_radio_configurations = num_radio_configurations;
    memcpy(dst_radio_combination_ptr->radio_configurations, radio_configuration,
           num_radio_configurations * sizeof(legacy_hal::wifi_radio_configuration));
}

void verifyRadioCombination(WifiRadioCombination* radioCombination, size_t num_radio_configurations,
                            legacy_hal::wifi_radio_configuration* radio_configuration) {
    EXPECT_EQ(num_radio_configurations, radioCombination->radioConfigurations.size());
    for (size_t i = 0; i < num_radio_configurations; i++) {
        EXPECT_EQ(hidl_struct_util::convertLegacyMacBandToHidlWifiBand(radio_configuration->band),
                  radioCombination->radioConfigurations[i].bandInfo);
        EXPECT_EQ(hidl_struct_util::convertLegacyAntennaConfigurationToHidl(
                          radio_configuration->antenna_cfg),
                  radioCombination->radioConfigurations[i].antennaMode);
        radio_configuration++;
    }
}

TEST_F(HidlStructUtilTest, canConvertLegacyRadioCombinationsMatrixToHidl) {
    legacy_hal::wifi_radio_configuration radio_configurations_array1[] = {
            {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_1X1},
    };
    legacy_hal::wifi_radio_configuration radio_configurations_array2[] = {
            {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_2X2},
            {.band = legacy_hal::WLAN_MAC_5_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_3X3},
    };
    legacy_hal::wifi_radio_configuration radio_configurations_array3[] = {
            {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_2X2},
            {.band = legacy_hal::WLAN_MAC_6_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_1X1},
            {.band = legacy_hal::WLAN_MAC_5_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_4X4},
    };

    int num_radio_configs = 0;
    int num_combinations = 0;
    std::array<char, 256> buffer;
    buffer.fill(0);
    legacy_hal::wifi_radio_combination_matrix* legacy_matrix =
            reinterpret_cast<wifi_radio_combination_matrix*>(buffer.data());
    legacy_hal::wifi_radio_combination* radio_combinations;

    // Prepare a legacy wifi_radio_combination_matrix
    legacy_matrix->num_radio_combinations = 3;
    // Insert first combination
    radio_combinations =
            (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations);
    insertRadioCombination(
            radio_combinations,
            sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]),
            radio_configurations_array1);
    num_combinations++;
    num_radio_configs +=
            sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]);

    // Insert second combination
    radio_combinations =
            (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations +
                                                  (num_combinations *
                                                   sizeof(legacy_hal::wifi_radio_combination)) +
                                                  (num_radio_configs *
                                                   sizeof(wifi_radio_configuration)));
    insertRadioCombination(
            radio_combinations,
            sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]),
            radio_configurations_array2);
    num_combinations++;
    num_radio_configs +=
            sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]);

    // Insert third combination
    radio_combinations =
            (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations +
                                                  (num_combinations *
                                                   sizeof(legacy_hal::wifi_radio_combination)) +
                                                  (num_radio_configs *
                                                   sizeof(wifi_radio_configuration)));
    insertRadioCombination(
            radio_combinations,
            sizeof(radio_configurations_array3) / sizeof(radio_configurations_array3[0]),
            radio_configurations_array3);

    V1_6::WifiRadioCombinationMatrix converted_matrix{};
    hidl_struct_util::convertLegacyRadioCombinationsMatrixToHidl(legacy_matrix, &converted_matrix);

    // Verify the conversion
    EXPECT_EQ(legacy_matrix->num_radio_combinations, converted_matrix.radioCombinations.size());
    verifyRadioCombination(
            &converted_matrix.radioCombinations[0],
            sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]),
            radio_configurations_array1);
    verifyRadioCombination(
            &converted_matrix.radioCombinations[1],
            sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]),
            radio_configurations_array2);
    verifyRadioCombination(
            &converted_matrix.radioCombinations[2],
            sizeof(radio_configurations_array3) / sizeof(radio_configurations_array3[0]),
            radio_configurations_array3);
}
}  // namespace implementation
}  // namespace V1_6
}  // namespace wifi
+28 −0
Original line number Diff line number Diff line
@@ -722,6 +722,12 @@ Return<void> WifiChip::getUsableChannels_1_6(
                           filterMask);
}

Return<void> WifiChip::getSupportedRadioCombinationsMatrix(
        getSupportedRadioCombinationsMatrix_cb hidl_status_cb) {
    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
                           &WifiChip::getSupportedRadioCombinationsMatrixInternal, hidl_status_cb);
}

void WifiChip::invalidateAndRemoveAllIfaces() {
    invalidateAndClearBridgedApAll();
    invalidateAndClearAll(ap_ifaces_);
@@ -1461,6 +1467,28 @@ std::pair<WifiStatus, std::vector<V1_6::WifiUsableChannel>> WifiChip::getUsableC
    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels};
}

std::pair<WifiStatus, V1_6::WifiRadioCombinationMatrix>
WifiChip::getSupportedRadioCombinationsMatrixInternal() {
    legacy_hal::wifi_error legacy_status;
    legacy_hal::wifi_radio_combination_matrix* legacy_matrix;

    std::tie(legacy_status, legacy_matrix) =
            legacy_hal_.lock()->getSupportedRadioCombinationsMatrix();
    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
        LOG(ERROR) << "Failed to get SupportedRadioCombinations matrix from legacy HAL: "
                   << legacyErrorToString(legacy_status);
        return {createWifiStatusFromLegacyError(legacy_status), {}};
    }

    V1_6::WifiRadioCombinationMatrix hidl_matrix;
    if (!hidl_struct_util::convertLegacyRadioCombinationsMatrixToHidl(legacy_matrix,
                                                                      &hidl_matrix)) {
        LOG(ERROR) << "Failed convertLegacyRadioCombinationsMatrixToHidl() ";
        return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), {}};
    }
    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_matrix};
}

WifiStatus WifiChip::handleChipConfiguration(
        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
    // If the chip is already configured in a different mode, stop
Loading