From c6f570378bd657db956366f406ce7291b06164e2 Mon Sep 17 00:00:00 2001 From: chenpaul Date: Fri, 5 Mar 2021 17:06:50 +0800 Subject: [PATCH] Add API "startSubsystemRestart" and callback function In order to trigger subsystem restart to reload wlan firmware, this change adds an API for framework and vendor HAL. Meanwhile, create new callback function for subsystem restart instead of general callback "onFailure()". Bug: 178126071 Test: vendor HAL can received API call subsystem restart will callback "onSubsystemRestart()" Change-Id: If3dc84049a9171677ad281c9bcc67a44dc722bdb --- wifi/1.5/IWifiChip.hal | 21 +++++++++++++++++++++ wifi/1.5/IWifiEventCallback.hal | 9 ++++++++- wifi/1.5/default/wifi.cpp | 2 +- wifi/1.5/default/wifi_chip.cpp | 12 ++++++++++++ wifi/1.5/default/wifi_chip.h | 3 +++ wifi/1.5/default/wifi_legacy_hal.cpp | 4 ++++ wifi/1.5/default/wifi_legacy_hal.h | 2 ++ wifi/1.5/default/wifi_legacy_hal_stubs.cpp | 1 + 8 files changed, 52 insertions(+), 2 deletions(-) diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index 5a3e2883d5..e199850c1a 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -303,4 +303,25 @@ interface IWifiChip extends @1.4::IWifiChip { getUsableChannels(WifiBand band, bitfield ifaceModeMask, bitfield filterMask) generates (WifiStatus status, vec channels); + + /** + * Trigger subsystem restart + * + * If the framework detects a problem (e.g. connection failure), + * it must call this function to attempt recovery. + * + * When the wifi HAL receiveds triggerSubsystemRestart(), it must restart + * the wlan subsystem, especially the wlan firmware. + * + * Regarding the callback function for subsystem restart, refer to documentation of + * |IWifiEventCallback.onSubsystemRestart| for details. + * + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, + * |WifiStatusCode.ERROR_NOT_AVAILABLE|, + * |WifiStatusCode.ERROR_UNKNOWN| + */ + triggerSubsystemRestart() generates (WifiStatus status); }; diff --git a/wifi/1.5/IWifiEventCallback.hal b/wifi/1.5/IWifiEventCallback.hal index 17dce39950..ff276306fd 100644 --- a/wifi/1.5/IWifiEventCallback.hal +++ b/wifi/1.5/IWifiEventCallback.hal @@ -17,5 +17,12 @@ package android.hardware.wifi@1.5; import @1.0::IWifiEventCallback; +import @1.0::WifiStatus; -interface IWifiEventCallback extends @1.0::IWifiEventCallback {}; +interface IWifiEventCallback extends @1.0::IWifiEventCallback { + /** + * Must be called when the Wi-Fi subsystem restart completes. + * Once this event is received, framework must fully reset the Wi-Fi stack state. + */ + oneway onSubsystemRestart(WifiStatus status); +}; diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.5/default/wifi.cpp index b4037e9907..b9f20a4615 100644 --- a/wifi/1.5/default/wifi.cpp +++ b/wifi/1.5/default/wifi.cpp @@ -131,7 +131,7 @@ WifiStatus Wifi::startInternal() { WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error); for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onFailure(wifi_status).isOk()) { + if (!callback->onSubsystemRestart(wifi_status).isOk()) { LOG(ERROR) << "Failed to invoke onFailure callback"; } } diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 0499f456c1..961f9da4c2 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -747,6 +747,13 @@ Return WifiChip::getUsableChannels( ifaceModeMask, filterMask); } +Return WifiChip::triggerSubsystemRestart( + triggerSubsystemRestart_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::triggerSubsystemRestartInternal, + hidl_status_cb); +} + void WifiChip::invalidateAndRemoveAllIfaces() { invalidateAndClearBridgedApAll(); invalidateAndClearAll(ap_ifaces_); @@ -1522,6 +1529,11 @@ WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask, return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels}; } +WifiStatus WifiChip::triggerSubsystemRestartInternal() { + auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart(); + return createWifiStatusFromLegacyError(legacy_status); +} + WifiStatus WifiChip::handleChipConfiguration( /* NONNULL */ std::unique_lock* lock, ChipModeId mode_id) { diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 92d639f8b5..bd40ead35a 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -184,6 +184,8 @@ class WifiChip : public V1_5::IWifiChip { WifiBand band, hidl_bitfield ifaceModeMask, hidl_bitfield filterMask, getUsableChannels_cb _hidl_cb) override; + Return triggerSubsystemRestart( + triggerSubsystemRestart_cb hidl_status_cb) override; private: void invalidateAndRemoveAllIfaces(); @@ -303,6 +305,7 @@ class WifiChip : public V1_5::IWifiChip { void invalidateAndClearBridgedApAll(); void invalidateAndClearBridgedAp(const std::string& br_name); bool findUsingNameFromBridgedApInstances(const std::string& name); + WifiStatus triggerSubsystemRestartInternal(); ChipId chip_id_; std::weak_ptr legacy_hal_; diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 45ad84b8c1..848fbd6114 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -1676,6 +1676,10 @@ WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask, return {status, std::move(channels)}; } +wifi_error WifiLegacyHal::triggerSubsystemRestart() { + return global_func_table_.wifi_trigger_subsystem_restart(); +} + void WifiLegacyHal::invalidate() { global_handle_ = nullptr; iface_name_to_handle_.clear(); diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 8ebc66aaa6..2bb7631efa 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -716,6 +716,8 @@ class WifiLegacyHal { std::pair> getUsableChannels( uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask); + wifi_error triggerSubsystemRestart(); + private: // Retrieve interface handles for all the available interfaces. wifi_error retrieveIfaceHandles(); diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp index 6212960d7a..dd860d6920 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -160,6 +160,7 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_twt_clear_stats); populateStubFor(&hal_fn->wifi_set_dtim_config); populateStubFor(&hal_fn->wifi_get_usable_channels); + populateStubFor(&hal_fn->wifi_trigger_subsystem_restart); return true; } } // namespace legacy_hal