From a903d316919366e1c2d9f3bb3a4f7051a75c6e8f Mon Sep 17 00:00:00 2001 From: Leon Yen Date: Tue, 6 Feb 2024 16:53:04 +0800 Subject: [PATCH] wifi: mt76: mt7921: fix a potential association failure upon resuming In multi-channel scenarios, the granted channel must be aborted before suspending. Otherwise, the firmware will be put into a wrong state, resulting in an association failure after resuming. With this patch, the granted channel will be aborted before suspending if necessary. Signed-off-by: Leon Yen Signed-off-by: Ming Yen Hsieh Signed-off-by: Felix Fietkau --- mt7921/main.c | 13 +++++++++++++ mt7921/mt7921.h | 1 + mt7921/pci.c | 2 ++ mt7921/sdio.c | 2 ++ 4 files changed, 18 insertions(+) diff --git a/mt7921/main.c b/mt7921/main.c index aa0cd78f..35f8997e 100644 --- a/mt7921/main.c +++ b/mt7921/main.c @@ -328,6 +328,19 @@ static void mt7921_roc_iter(void *priv, u8 *mac, mt7921_mcu_abort_roc(phy, mvif, phy->roc_token_id); } +void mt7921_roc_abort_sync(struct mt792x_dev *dev) +{ + struct mt792x_phy *phy = &dev->phy; + + del_timer_sync(&phy->roc_timer); + cancel_work_sync(&phy->roc_work); + if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) + ieee80211_iterate_active_interfaces(mt76_hw(dev), + IEEE80211_IFACE_ITER_RESUME_ALL, + mt7921_roc_iter, (void *)phy); +} +EXPORT_SYMBOL_GPL(mt7921_roc_abort_sync); + void mt7921_roc_work(struct work_struct *work) { struct mt792x_phy *phy; diff --git a/mt7921/mt7921.h b/mt7921/mt7921.h index 1cb21133..3016636d 100644 --- a/mt7921/mt7921.h +++ b/mt7921/mt7921.h @@ -322,4 +322,5 @@ int mt7921_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_vif *vif, enum mt7921_roc_req type, u8 token_id); int mt7921_mcu_abort_roc(struct mt792x_phy *phy, struct mt792x_vif *vif, u8 token_id); +void mt7921_roc_abort_sync(struct mt792x_dev *dev); #endif diff --git a/mt7921/pci.c b/mt7921/pci.c index 384dcb51..969a8972 100644 --- a/mt7921/pci.c +++ b/mt7921/pci.c @@ -406,6 +406,8 @@ static int mt7921_pci_suspend(struct device *device) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); + mt7921_roc_abort_sync(dev); + err = mt792x_mcu_drv_pmctrl(dev); if (err < 0) goto restore_suspend; diff --git a/mt7921/sdio.c b/mt7921/sdio.c index bd556247..ae9c0d43 100644 --- a/mt7921/sdio.c +++ b/mt7921/sdio.c @@ -217,6 +217,8 @@ static int mt7921s_suspend(struct device *__dev) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); + mt7921_roc_abort_sync(dev); + err = mt792x_mcu_drv_pmctrl(dev); if (err < 0) goto restore_suspend;