wifi: ath10k: Avoid vdev delete timeout when firmware is already down
In some scenarios, the firmware may be stopped before the interface is removed, either due to a crash or because the remoteproc (e.g., MPSS) is shut down early during system reboot or shutdown. This leads to a delay during interface teardown, as the driver waits for a vdev delete response that never arrives, eventually timing out. Example (SNOC): $ echo stop > /sys/class/remoteproc/remoteproc0/state [ 71.64] remoteproc remoteproc0: stopped remote processor modem $ reboot [ 74.84] ath10k_snoc c800000.wifi: failed to transmit packet, dropping: -108 [ 74.84] ath10k_snoc c800000.wifi: failed to submit frame: -108 [...] [ 82.39] ath10k_snoc c800000.wifi: Timeout in receiving vdev delete response To avoid this, skip waiting for the vdev delete response if the firmware is already marked as unreachable (`ATH10K_FLAG_CRASH_FLUSH`), similar to how `ath10k_mac_wait_tx_complete()` and `ath10k_vdev_setup_sync()` handle this case. Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com> Link: https://patch.msgid.link/20250522131704.612206-1-loic.poulain@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
committed by
Jeff Johnson
parent
1650d32b92
commit
dc9c4252fe
@@ -4,6 +4,7 @@
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "mac.h"
|
||||
@@ -1022,6 +1023,26 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
|
||||
return ar->last_wmi_vdev_start_status;
|
||||
}
|
||||
|
||||
static inline int ath10k_vdev_delete_sync(struct ath10k *ar)
|
||||
{
|
||||
unsigned long time_left;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
if (!test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map))
|
||||
return 0;
|
||||
|
||||
if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
|
||||
return -ESHUTDOWN;
|
||||
|
||||
time_left = wait_for_completion_timeout(&ar->vdev_delete_done,
|
||||
ATH10K_VDEV_DELETE_TIMEOUT_HZ);
|
||||
if (time_left == 0)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
|
||||
{
|
||||
struct cfg80211_chan_def *chandef = NULL;
|
||||
@@ -5900,7 +5921,6 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
struct ath10k_peer *peer;
|
||||
unsigned long time_left;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@@ -5940,13 +5960,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
|
||||
ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
|
||||
if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) {
|
||||
time_left = wait_for_completion_timeout(&ar->vdev_delete_done,
|
||||
ATH10K_VDEV_DELETE_TIMEOUT_HZ);
|
||||
if (time_left == 0) {
|
||||
ath10k_warn(ar, "Timeout in receiving vdev delete response\n");
|
||||
goto out;
|
||||
}
|
||||
ret = ath10k_vdev_delete_sync(ar);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "Error in receiving vdev delete response: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Some firmware revisions don't notify host about self-peer removal
|
||||
|
||||
Reference in New Issue
Block a user