wifi: mt76: mt7921e: add pci .shutdown() support
authorLeon Yen <Leon.Yen@mediatek.com>
Thu, 1 Dec 2022 10:38:42 +0000 (18:38 +0800)
committerFelix Fietkau <nbd@nbd.name>
Thu, 1 Dec 2022 16:29:15 +0000 (17:29 +0100)
Some combinations of hosts cannnot detect mt7921e after reboot. The
interoperability issue is caused by the status mismatch between host
and chip fw. In such cases, the driver should stop chip activities
and reset chip to default state before reboot.

Suggested-by: angelogioacchino.delregno@collabora.com
Co-developed-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Leon Yen <Leon.Yen@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7921/pci.c

index 28342ec940f06332ceb7dc4586aea0c3ab589062..cb72ded372564ea5bf52bea2f66e80cab767fe9a 100644 (file)
@@ -507,6 +507,21 @@ failed:
        return err;
 }
 
+static void mt7921_pci_shutdown(struct pci_dev *pdev)
+{
+       struct mt76_dev *mdev = pci_get_drvdata(pdev);
+       struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
+       struct mt76_connac_pm *pm = &dev->pm;
+
+       cancel_delayed_work_sync(&pm->ps_work);
+       cancel_work_sync(&pm->wake_work);
+
+       /* chip cleanup before reboot */
+       mt7921_mcu_drv_pmctrl(dev);
+       mt7921_dma_cleanup(dev);
+       mt7921_wfsys_reset(dev);
+}
+
 static DEFINE_SIMPLE_DEV_PM_OPS(mt7921_pm_ops, mt7921_pci_suspend, mt7921_pci_resume);
 
 static struct pci_driver mt7921_pci_driver = {
@@ -514,6 +529,7 @@ static struct pci_driver mt7921_pci_driver = {
        .id_table       = mt7921_pci_device_table,
        .probe          = mt7921_pci_probe,
        .remove         = mt7921_pci_remove,
+       .shutdown       = mt7921_pci_shutdown,
        .driver.pm      = pm_sleep_ptr(&mt7921_pm_ops),
 };