wifi(hidl): Modify the SAR power levels interface
Modifying the interface used to lower the tx power level for meeting SAR requirements based on recommendation from the nexus hardware team. The previous interface passed in a single power value in dBm for meeting SAR requirements. However, the SAR requirements are more complex than that. Based on the connection mode (802.11 a,b,g,n,ac) and the number of streams that are active (MIMO), the SAR power levels are very different. Using the previous interface would mean that we will have to use the lowest power level among all the connection modes to meet the SAR requirements. This would however result in us lowering the power much more than needed (~2 dBm) for many connection modes. Instead, we're switching to a more generic interface where the framework informs the wifi chip that we're entering a special tx power mode scenario (today, there is only 1 for voice call). The chip can then lookup the extensive table of power levels for different connection modes which are pre-populated by the OEM's in the BDF file to set the power level (depending on the scenario framework sends and the active connection mode). Bug: 62437848 Test: Manual tests Change-Id: I5ee3f0d2c130958dbeb352e3b5ad9407f432624f
This commit is contained in:
parent
5614b96de5
commit
735ff43197
10 changed files with 83 additions and 53 deletions
|
@ -219,4 +219,4 @@ bb7c96762d0aa3ddb874c8815bacdd3cbc8fb87ea2f82b928bc29e24a3593055 android.hardwar
|
|||
c3354ab0d381a236c12dc486ad4b6bec28c979d26748b4661f12ede36f392808 android.hardware.wifi.offload@1.0::IOffloadCallback
|
||||
b18caefefcc765092412285d776234fcf213b73bdf07ae1b67a5f71b2d2464e3 android.hardware.wifi.offload@1.0::types
|
||||
c26473e2e4a00af43e28a0ddf9002e5062a7d0940429e5efb6e5513a8abcb75c android.hardware.wifi@1.1::IWifi
|
||||
bfcf4856c7b6c66ebc56785ed3e5d181b7be859c2add672497a843b024518737 android.hardware.wifi@1.1::IWifiChip
|
||||
b056e1defab4071584214584057d0bc73a613081bf1152590549649d4582c13c android.hardware.wifi@1.1::IWifiChip
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2016 The Android Open Source Project
|
||||
* Copyright 2017 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.
|
||||
|
@ -44,24 +44,40 @@ interface IWifiChip extends @1.0::IWifiChip {
|
|||
};
|
||||
|
||||
/**
|
||||
* API to set TX power limit.
|
||||
* This is used for meeting SAR requirements while making VOIP calls for
|
||||
* example.
|
||||
*
|
||||
* @param powerInDbm Power level in dBm.
|
||||
* @return status WifiStatus of the operation.
|
||||
* Possible status codes:
|
||||
* |WifiStatusCode.SUCCESS|,
|
||||
* |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
|
||||
* |WifiStatusCode.ERROR_NOT_SUPPORTED|,
|
||||
* |WifiStatusCode.NOT_AVAILABLE|,
|
||||
* |WifiStatusCode.UNKNOWN|
|
||||
* List of preset wifi radio TX power levels for different scenarios.
|
||||
* The actual power values (typically varies based on the channel,
|
||||
* 802.11 connection type, number of MIMO streams, etc) for each scenario
|
||||
* is defined by the OEM as a BDF file since it varies for each wifi chip
|
||||
* vendor and device.
|
||||
*/
|
||||
setTxPowerLimit(int32_t powerInDbm) generates (WifiStatus status);
|
||||
enum TxPowerScenario : uint32_t {
|
||||
VOICE_CALL = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* API to reset TX power limit.
|
||||
* This is used to set the power back to default values.
|
||||
* API to select one of the preset TX power scenarios.
|
||||
*
|
||||
* The framework must invoke this method with the appropriate scenario to let
|
||||
* the wifi chip change it's transmitting power levels.
|
||||
* OEM's should define various power profiles for each of the scenarios
|
||||
* above (defined in |TxPowerScenario|).
|
||||
*
|
||||
* @param scenario One of the preselected scenarios defined in
|
||||
* |TxPowerScenario|.
|
||||
* @return status WifiStatus of the operation.
|
||||
* Possible status codes:
|
||||
* |WifiStatusCode.SUCCESS|,
|
||||
* |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
|
||||
* |WifiStatusCode.ERROR_NOT_SUPPORTED|,
|
||||
* |WifiStatusCode.NOT_AVAILABLE|,
|
||||
* |WifiStatusCode.UNKNOWN|
|
||||
*/
|
||||
selectTxPowerScenario(TxPowerScenario scenario) generates (WifiStatus status);
|
||||
|
||||
/**
|
||||
* API to reset TX power levels.
|
||||
* This is used to indicate the end of the previously selected TX power
|
||||
* scenario and let the wifi chip fall back to the default power values.
|
||||
*
|
||||
* @return status WifiStatus of the operation.
|
||||
* Possible status codes:
|
||||
|
@ -71,5 +87,5 @@ interface IWifiChip extends @1.0::IWifiChip {
|
|||
* |WifiStatusCode.NOT_AVAILABLE|,
|
||||
* |WifiStatusCode.UNKNOWN|
|
||||
*/
|
||||
resetTxPowerLimit() generates (WifiStatus status);
|
||||
resetTxPowerScenario() generates (WifiStatus status);
|
||||
};
|
||||
|
|
|
@ -17,9 +17,6 @@
|
|||
#include <android-base/logging.h>
|
||||
#include <utils/SystemClock.h>
|
||||
|
||||
#include <android/hardware/wifi/1.0/IWifiChip.h>
|
||||
#include <android/hardware/wifi/1.1/IWifiChip.h>
|
||||
|
||||
#include "hidl_struct_util.h"
|
||||
|
||||
namespace android {
|
||||
|
@ -260,6 +257,15 @@ bool convertLegacyWakeReasonStatsToHidl(
|
|||
return true;
|
||||
}
|
||||
|
||||
legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
|
||||
V1_1::IWifiChip::TxPowerScenario hidl_scenario) {
|
||||
switch (hidl_scenario) {
|
||||
case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL:
|
||||
return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL;
|
||||
};
|
||||
CHECK(false);
|
||||
}
|
||||
|
||||
bool convertLegacyFeaturesToHidlStaCapabilities(
|
||||
uint32_t legacy_feature_set,
|
||||
uint32_t legacy_logger_feature_set,
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <vector>
|
||||
|
||||
#include <android/hardware/wifi/1.0/types.h>
|
||||
#include <android/hardware/wifi/1.0/IWifiChip.h>
|
||||
#include <android/hardware/wifi/1.1/IWifiChip.h>
|
||||
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
|
@ -51,6 +53,8 @@ bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
|
|||
bool convertLegacyWakeReasonStatsToHidl(
|
||||
const legacy_hal::WakeReasonStats& legacy_stats,
|
||||
WifiDebugHostWakeReasonStats* hidl_stats);
|
||||
legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
|
||||
V1_1::IWifiChip::TxPowerScenario hidl_scenario);
|
||||
|
||||
// STA iface conversion methods.
|
||||
bool convertLegacyFeaturesToHidlStaCapabilities(
|
||||
|
|
|
@ -343,20 +343,20 @@ Return<void> WifiChip::enableDebugErrorAlerts(
|
|||
enable);
|
||||
}
|
||||
|
||||
Return<void> WifiChip::setTxPowerLimit(
|
||||
int32_t powerInDbm, setTxPowerLimit_cb hidl_status_cb) {
|
||||
Return<void> WifiChip::selectTxPowerScenario(
|
||||
TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
|
||||
return validateAndCall(this,
|
||||
WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
|
||||
&WifiChip::setTxPowerLimitInternal,
|
||||
&WifiChip::selectTxPowerScenarioInternal,
|
||||
hidl_status_cb,
|
||||
powerInDbm);
|
||||
scenario);
|
||||
}
|
||||
|
||||
Return<void> WifiChip::resetTxPowerLimit(
|
||||
resetTxPowerLimit_cb hidl_status_cb) {
|
||||
Return<void> WifiChip::resetTxPowerScenario(
|
||||
resetTxPowerScenario_cb hidl_status_cb) {
|
||||
return validateAndCall(this,
|
||||
WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
|
||||
&WifiChip::resetTxPowerLimitInternal,
|
||||
&WifiChip::resetTxPowerScenarioInternal,
|
||||
hidl_status_cb);
|
||||
}
|
||||
|
||||
|
@ -824,13 +824,14 @@ WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
|
|||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
WifiStatus WifiChip::setTxPowerLimitInternal(int32_t powerInDbm) {
|
||||
auto legacy_status = legacy_hal_.lock()->setTxPowerLimit(powerInDbm);
|
||||
WifiStatus WifiChip::selectTxPowerScenarioInternal(TxPowerScenario scenario) {
|
||||
auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
|
||||
hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
WifiStatus WifiChip::resetTxPowerLimitInternal() {
|
||||
auto legacy_status = legacy_hal_.lock()->resetTxPowerLimit();
|
||||
WifiStatus WifiChip::resetTxPowerScenarioInternal() {
|
||||
auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario();
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
|
|
|
@ -126,9 +126,11 @@ class WifiChip : public V1_1::IWifiChip {
|
|||
getDebugHostWakeReasonStats_cb hidl_status_cb) override;
|
||||
Return<void> enableDebugErrorAlerts(
|
||||
bool enable, enableDebugErrorAlerts_cb hidl_status_cb) override;
|
||||
Return<void> setTxPowerLimit(
|
||||
int32_t powerInDbm, setTxPowerLimit_cb hidl_status_cb) override;
|
||||
Return<void> resetTxPowerLimit(resetTxPowerLimit_cb hidl_status_cb) override;
|
||||
Return<void> selectTxPowerScenario(
|
||||
TxPowerScenario scenario,
|
||||
selectTxPowerScenario_cb hidl_status_cb) override;
|
||||
Return<void> resetTxPowerScenario(
|
||||
resetTxPowerScenario_cb hidl_status_cb) override;
|
||||
|
||||
private:
|
||||
void invalidateAndRemoveAllIfaces();
|
||||
|
@ -180,8 +182,8 @@ class WifiChip : public V1_1::IWifiChip {
|
|||
std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
|
||||
getDebugHostWakeReasonStatsInternal();
|
||||
WifiStatus enableDebugErrorAlertsInternal(bool enable);
|
||||
WifiStatus setTxPowerLimitInternal(int32_t powerInDbm);
|
||||
WifiStatus resetTxPowerLimitInternal();
|
||||
WifiStatus selectTxPowerScenarioInternal(TxPowerScenario scenario);
|
||||
WifiStatus resetTxPowerScenarioInternal();
|
||||
|
||||
WifiStatus handleChipConfiguration(ChipModeId mode_id);
|
||||
WifiStatus registerDebugRingBufferCallback();
|
||||
|
|
|
@ -752,13 +752,13 @@ wifi_error WifiLegacyHal::setScanningMacOui(const std::array<uint8_t, 3>& oui) {
|
|||
oui_internal.data());
|
||||
}
|
||||
|
||||
wifi_error WifiLegacyHal::setTxPowerLimit(int32_t tx_level_dbm) {
|
||||
return global_func_table_.wifi_set_tx_power_limit(wlan_interface_handle_,
|
||||
tx_level_dbm);
|
||||
wifi_error WifiLegacyHal::selectTxPowerScenario(wifi_power_scenario scenario) {
|
||||
return global_func_table_.wifi_select_tx_power_scenario(
|
||||
wlan_interface_handle_, scenario);
|
||||
}
|
||||
|
||||
wifi_error WifiLegacyHal::resetTxPowerLimit() {
|
||||
return global_func_table_.wifi_reset_tx_power_limit(wlan_interface_handle_);
|
||||
wifi_error WifiLegacyHal::resetTxPowerScenario() {
|
||||
return global_func_table_.wifi_reset_tx_power_scenario(wlan_interface_handle_);
|
||||
}
|
||||
|
||||
std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet() {
|
||||
|
|
|
@ -205,8 +205,8 @@ class WifiLegacyHal {
|
|||
uint32_t period_in_ms);
|
||||
wifi_error stopSendingOffloadedPacket(uint32_t cmd_id);
|
||||
wifi_error setScanningMacOui(const std::array<uint8_t, 3>& oui);
|
||||
wifi_error setTxPowerLimit(int32_t tx_level_dbm);
|
||||
wifi_error resetTxPowerLimit();
|
||||
wifi_error selectTxPowerScenario(wifi_power_scenario scenario);
|
||||
wifi_error resetTxPowerScenario();
|
||||
// Logger/debug functions.
|
||||
std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet();
|
||||
wifi_error startPktFateMonitoring();
|
||||
|
|
|
@ -132,8 +132,8 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) {
|
|||
populateStubFor(&hal_fn->wifi_get_roaming_capabilities);
|
||||
populateStubFor(&hal_fn->wifi_enable_firmware_roaming);
|
||||
populateStubFor(&hal_fn->wifi_configure_roaming);
|
||||
populateStubFor(&hal_fn->wifi_set_tx_power_limit);
|
||||
populateStubFor(&hal_fn->wifi_reset_tx_power_limit);
|
||||
populateStubFor(&hal_fn->wifi_select_tx_power_scenario);
|
||||
populateStubFor(&hal_fn->wifi_reset_tx_power_scenario);
|
||||
return true;
|
||||
}
|
||||
} // namespace legacy_hal
|
||||
|
|
|
@ -37,7 +37,8 @@ using ::android::hardware::wifi::V1_1::IWifiChip;
|
|||
using ::android::hardware::wifi::V1_0::IWifiStaIface;
|
||||
|
||||
namespace {
|
||||
constexpr int32_t kFakePowerInDbm = -56;
|
||||
constexpr IWifiChip::TxPowerScenario kFakePowerScenario =
|
||||
IWifiChip::TxPowerScenario::VOICE_CALL;
|
||||
}; //namespace
|
||||
|
||||
/**
|
||||
|
@ -66,12 +67,12 @@ class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
|||
};
|
||||
|
||||
/*
|
||||
* SetTxPowerLimit
|
||||
* SelectTxPowerScenario
|
||||
*/
|
||||
TEST_F(WifiChipHidlTest, SetTxPowerLimit) {
|
||||
TEST_F(WifiChipHidlTest, SelectTxPowerScenario) {
|
||||
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
|
||||
const auto& status =
|
||||
HIDL_INVOKE(wifi_chip_, setTxPowerLimit, kFakePowerInDbm);
|
||||
HIDL_INVOKE(wifi_chip_, selectTxPowerScenario, kFakePowerScenario);
|
||||
if (caps & IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT) {
|
||||
EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
|
||||
} else {
|
||||
|
@ -80,12 +81,12 @@ TEST_F(WifiChipHidlTest, SetTxPowerLimit) {
|
|||
}
|
||||
|
||||
/*
|
||||
* SetTxPowerLimit
|
||||
* ResetTxPowerScenario
|
||||
*/
|
||||
TEST_F(WifiChipHidlTest, ResetTxPowerLimit) {
|
||||
TEST_F(WifiChipHidlTest, ResetTxPowerScenario) {
|
||||
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
|
||||
const auto& status =
|
||||
HIDL_INVOKE(wifi_chip_, resetTxPowerLimit);
|
||||
HIDL_INVOKE(wifi_chip_, resetTxPowerScenario);
|
||||
if (caps & IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT) {
|
||||
EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue