Skip to content

Commit

Permalink
wifi: mt76: mt7921s: fix race issue between reset and suspend/resume
Browse files Browse the repository at this point in the history
It is unexpected that the reset work is running simultaneously with
the suspend or resume context and it is possible that reset work is still
running even after mt7921 is suspended if we don't fix the race issue.

Thus, the suspend procedure should be waiting until the reset is completed
at the beginning and ignore the subsequent the reset requests.

In case there is an error that happens during either suspend or resume
handler, we will schedule a reset task to recover the error before
returning the error code to ensure we can immediately fix the error there.

Fixes: ca74b9b907f9 ("mt76: mt7921s: add reset support")
Co-developed-by: YN Chen <YN.Chen@mediatek.com>
Signed-off-by: YN Chen <YN.Chen@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
  • Loading branch information
moore-bros authored and nbd168 committed Sep 15, 2022
1 parent 67fbdb7 commit a9b09dd
Showing 1 changed file with 9 additions and 4 deletions.
13 changes: 9 additions & 4 deletions mt7921/sdio.c
Expand Up @@ -206,6 +206,7 @@ static int mt7921s_suspend(struct device *__dev)
pm->suspended = true;
set_bit(MT76_STATE_SUSPEND, &mdev->phy.state);

flush_work(&dev->reset_work);
cancel_delayed_work_sync(&pm->ps_work);
cancel_work_sync(&pm->wake_work);

Expand Down Expand Up @@ -261,6 +262,9 @@ static int mt7921s_suspend(struct device *__dev)
clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
pm->suspended = false;

if (err < 0)
mt7921_reset(&dev->mt76);

return err;
}

Expand All @@ -276,7 +280,7 @@ static int mt7921s_resume(struct device *__dev)

err = mt7921_mcu_drv_pmctrl(dev);
if (err < 0)
return err;
goto failed;

mt76_worker_enable(&mdev->tx_worker);
mt76_worker_enable(&mdev->sdio.txrx_worker);
Expand All @@ -288,11 +292,12 @@ static int mt7921s_resume(struct device *__dev)
mt76_connac_mcu_set_deep_sleep(mdev, false);

err = mt76_connac_mcu_set_hif_suspend(mdev, false);
if (err)
return err;

failed:
pm->suspended = false;

if (err < 0)
mt7921_reset(&dev->mt76);

return err;
}

Expand Down

0 comments on commit a9b09dd

Please sign in to comment.