RE: [PATCH v5 1/3] wifi: rtw88: clear RTW_FLAG_RESTARTING on stop and start failure
From: Zong-Zhe Yang
Date: Fri Nov 13 2026 - 06:43:08 EST
Kalpesh Solanki <skalpesh942@xxxxxxxxx> wrote:
>
> When mac80211 stops or suspends the device without WoWLAN,
> drv_reconfig_complete() is never invoked with
> IEEE80211_RECONFIG_TYPE_RESTART. If firmware recovery was in flight
> during this transition, RTW_FLAG_RESTARTING remains set permanently,
> blocking all subsequent firmware recoveries until the module is reloaded.
>
In this case, I saw you clear RTW_FLAG_RESTARTING in rtw_ops_stop.
However, the reconfig flow might not have even run at that moment.
How about clearing RTW_FLAG_RESTARTING when driver gets
IEEE80211_RECONFIG_TYPE_SUSPEND?
>
> Similarly, if rtw_core_start() fails during drv_start() in a recovery
> restart, local->started remains false. When mac80211 cleans up via
> cfg80211_shutdown_all_interfaces(), drv_stop() returns early without
> calling rtw_ops_stop(), leaving RTW_FLAG_RESTARTING set permanently on
> hardware that failed to recover.
>
> Clear RTW_FLAG_RESTARTING in rtw_ops_stop(), as well as in
> rtw_ops_start() when rtw_core_start() returns an error, ensuring the
> driver always exits the restarting state on error or teardown.
>
> Fixes: 5c831644e1f4 ("rtw88: handle and recover when firmware crash")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Kalpesh Solanki <skalpesh942@xxxxxxxxx>
> ---
> drivers/net/wireless/realtek/rtw88/mac80211.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c
> b/drivers/net/wireless/realtek/rtw88/mac80211.c
> index 5e40cf06a9e..ffd86f08185 100644
> --- a/drivers/net/wireless/realtek/rtw88/mac80211.c
> +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
> @@ -57,6 +57,8 @@ static int rtw_ops_start(struct ieee80211_hw *hw)
>
> mutex_lock(&rtwdev->mutex);
> ret = rtw_core_start(rtwdev);
> + if (ret)
> + clear_bit(RTW_FLAG_RESTARTING, rtwdev->flags);
> mutex_unlock(&rtwdev->mutex);
>
> return ret;
> @@ -67,6 +69,7 @@ static void rtw_ops_stop(struct ieee80211_hw *hw, bool
> suspend)
> struct rtw_dev *rtwdev = hw->priv;
>
> mutex_lock(&rtwdev->mutex);
> + clear_bit(RTW_FLAG_RESTARTING, rtwdev->flags);
> rtw_core_stop(rtwdev);
> mutex_unlock(&rtwdev->mutex);
> }
> --
> 2.53.0
>