Message ID | 28482de35c4f1589dcf96b662a48bc558fe46e8f.1669361180.git.deren.wu@mediatek.com |
---|---|
State | New |
Headers | show |
Series | wifi: mt76: mt7921e: introduce reboot notifier support | expand |
On 25.11.22 08:36, Deren Wu wrote: > From: Leon Yen <Leon.Yen@mediatek.com> > > 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. > > 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> This doesn't just affect mt7921. There are some platforms where similar issues have been reported with mt7915 or mt7615. I think we should move some parts of this to mt76 (and mt76-connac) core. - Felix
Hi Felix On Mon, 2022-11-28 at 10:26 +0100, Felix Fietkau wrote: > On 25.11.22 08:36, Deren Wu wrote: > > From: Leon Yen <Leon.Yen@mediatek.com> > > > > 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. > > > > 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> > > This doesn't just affect mt7921. There are some platforms where > similar > issues have been reported with mt7915 or mt7615. > I think we should move some parts of this to mt76 (and mt76-connac) > core. > > - Felix > Sure, I will post mt76 arch + mt7921e implement in v2. Regards, Deren
On Tue, 2022-11-29 at 01:11 +0000, Deren Wu (武德仁) wrote: > Hi Felix > > On Mon, 2022-11-28 at 10:26 +0100, Felix Fietkau wrote: > > On 25.11.22 08:36, Deren Wu wrote: > > > From: Leon Yen <Leon.Yen@mediatek.com> > > > > > > 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. > > > > > > 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> > > > > This doesn't just affect mt7921. There are some platforms where > > similar > > issues have been reported with mt7915 or mt7615. > > I think we should move some parts of this to mt76 (and mt76-connac) > > core. > > > > - Felix > > > > Sure, I will post mt76 arch + mt7921e implement in v2. > > Regards, > Deren This is an userful finding. mt7915 still calls wfsys_reset at the beginning of probe() to deal with bootup/module_reload issues. Ryder
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 6fc04ed34ec3..64156d32b62d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -306,6 +306,7 @@ struct mt7921_dev { struct sk_buff_head ipv6_ns_list; enum environment_cap country_ie_env; + struct notifier_block reboot_nb; }; enum { diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index 28342ec940f0..6d20b3ed5db1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -6,6 +6,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/reboot.h> #include "mt7921.h" #include "mac.h" @@ -110,6 +111,7 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev) struct mt76_connac_pm *pm = &dev->pm; cancel_work_sync(&dev->init_work); + unregister_reboot_notifier(&dev->reboot_nb); mt76_unregister_device(&dev->mt76); mt76_for_each_q_rx(&dev->mt76, i) napi_disable(&dev->mt76.napi[i]); @@ -226,6 +228,24 @@ static u32 mt7921_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) return dev->bus_ops->rmw(mdev, addr, mask, val); } +static int mt7921e_reboot_notifier(struct notifier_block *nb, + unsigned long code, void *unused) +{ + struct mt7921_dev *dev = container_of(nb, struct mt7921_dev, + reboot_nb); + 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); + + return NOTIFY_DONE; +} + static int mt7921_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -361,6 +381,11 @@ static int mt7921_pci_probe(struct pci_dev *pdev, if (ret) goto err_free_irq; + dev->reboot_nb.notifier_call = mt7921e_reboot_notifier; + ret = register_reboot_notifier(&dev->reboot_nb); + if (ret) + goto err_free_irq; + return 0; err_free_irq: