Skip to content

Commit dc9c425

Browse files
Loic Poulainjeff-t-johnson
authored andcommitted
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 <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jeff Johnson <[email protected]>
1 parent 1650d32 commit dc9c425

File tree

1 file changed

+25
-8
lines changed
  • drivers/net/wireless/ath/ath10k

1 file changed

+25
-8
lines changed

drivers/net/wireless/ath/ath10k/mac.c

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
55
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
66
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
7+
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
78
*/
89

910
#include "mac.h"
@@ -1022,6 +1023,26 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
10221023
return ar->last_wmi_vdev_start_status;
10231024
}
10241025

1026+
static inline int ath10k_vdev_delete_sync(struct ath10k *ar)
1027+
{
1028+
unsigned long time_left;
1029+
1030+
lockdep_assert_held(&ar->conf_mutex);
1031+
1032+
if (!test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map))
1033+
return 0;
1034+
1035+
if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
1036+
return -ESHUTDOWN;
1037+
1038+
time_left = wait_for_completion_timeout(&ar->vdev_delete_done,
1039+
ATH10K_VDEV_DELETE_TIMEOUT_HZ);
1040+
if (time_left == 0)
1041+
return -ETIMEDOUT;
1042+
1043+
return 0;
1044+
}
1045+
10251046
static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
10261047
{
10271048
struct cfg80211_chan_def *chandef = NULL;
@@ -5900,7 +5921,6 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
59005921
struct ath10k *ar = hw->priv;
59015922
struct ath10k_vif *arvif = (void *)vif->drv_priv;
59025923
struct ath10k_peer *peer;
5903-
unsigned long time_left;
59045924
int ret;
59055925
int i;
59065926

@@ -5940,13 +5960,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
59405960
ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
59415961
arvif->vdev_id, ret);
59425962

5943-
if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) {
5944-
time_left = wait_for_completion_timeout(&ar->vdev_delete_done,
5945-
ATH10K_VDEV_DELETE_TIMEOUT_HZ);
5946-
if (time_left == 0) {
5947-
ath10k_warn(ar, "Timeout in receiving vdev delete response\n");
5948-
goto out;
5949-
}
5963+
ret = ath10k_vdev_delete_sync(ar);
5964+
if (ret) {
5965+
ath10k_warn(ar, "Error in receiving vdev delete response: %d\n", ret);
5966+
goto out;
59505967
}
59515968

59525969
/* Some firmware revisions don't notify host about self-peer removal

0 commit comments

Comments
 (0)