Message ID | d44631bcc74cce3f32a72f616a99d1bd2837690f.1669711916.git.deren.wu@mediatek.com |
---|---|
State | New |
Headers | show |
Series | [v2,1/2] wifi: mt76: introduce reboot notifier support | expand |
Il 29/11/22 10:16, Deren Wu ha scritto: > From: Leon Yen <Leon.Yen@mediatek.com> > > cleanup/reset chip fw before reboot to avoid unstable problems in next run. > > 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> Apart from the comment in patch [1/1] .... I've noticed that this issue is present also on MT7915E: in my case, I have two of these cards installed on a nVidia Xavier NX Developer Kit and one on a Raspberry Pi 4 Compute Module mounted on an original CM4 IO Board. The two on Xavier NX are not showing this issue, but the Pi CM4 cannot see the card when rebooting the system... so that chip cleanup action should actually be replicated on mt7915/pci.c as well, if possible. Regards, Angelo > --- > .../net/wireless/mediatek/mt76/mt7921/pci.c | 21 +++++++++++++++++++ > 1 file changed, 21 insertions(+) > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > index 28342ec940f0..4e9021c349b9 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > @@ -226,6 +226,25 @@ 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 mt76_dev *mdev = container_of(nb, struct mt76_dev, > + reboot_nb); > + 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); > + > + return NOTIFY_DONE; > +} > + > static int mt7921_pci_probe(struct pci_dev *pdev, > const struct pci_device_id *id) > { > @@ -357,6 +376,8 @@ static int mt7921_pci_probe(struct pci_dev *pdev, > if (ret) > goto err_free_irq; > > + mdev->reboot_nb.notifier_call = mt7921e_reboot_notifier; > + > ret = mt7921_register_device(dev); > if (ret) > goto err_free_irq; >
Hi Angelo, On Tue, 2022-11-29 at 16:00 +0100, AngeloGioacchino Del Regno wrote: > Il 29/11/22 10:16, Deren Wu ha scritto: > > Some combinations of hosts cannnot detect wifi chip 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. > > > > This is a preliminary patch to add mt7921e reboot notifier support. > > > > Reviewed-by: Shayne Chen <shayne.chen@mediatek.com> > > Signed-off-by: Deren Wu <deren.wu@mediatek.com> > > If you want to perform shutdown actions when rebooting the machine, > this > means that you want to perform actions when shutting down the > kernel.... > > ...so, have you tried to perform such actions in the .shutdown() > callback > of your struct pci_driver? :-) > > Regards, > Angelo > This patch works fine with pci .shutdown(). Thanks for your comments :) I will drop this series and post a new version. Regards, Deren > > --- > > drivers/net/wireless/mediatek/mt76/mac80211.c | 21 > > +++++++++++++++++++ > > drivers/net/wireless/mediatek/mt76/mt76.h | 2 ++ > > 2 files changed, 23 insertions(+) > > > >
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index fc608b369b3c..a8515cb2527e 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -230,6 +230,22 @@ static void mt76_led_cleanup(struct mt76_dev *dev) led_classdev_unregister(&dev->led_cdev); } +static int mt76_notifier_init(struct mt76_dev *dev) +{ + if (!dev->reboot_nb.notifier_call) + return 0; + + return register_reboot_notifier(&dev->reboot_nb); +} + +static void mt76_notifier_cleanup(struct mt76_dev *dev) +{ + if (!dev->reboot_nb.notifier_call) + return; + + unregister_reboot_notifier(&dev->reboot_nb); +} + static void mt76_init_stream_cap(struct mt76_phy *phy, struct ieee80211_supported_band *sband, bool vht) @@ -658,6 +674,10 @@ int mt76_register_device(struct mt76_dev *dev, bool vht, return ret; } + ret = mt76_notifier_init(dev); + if (ret) + return ret; + ret = ieee80211_register_hw(hw); if (ret) return ret; @@ -675,6 +695,7 @@ void mt76_unregister_device(struct mt76_dev *dev) if (IS_ENABLED(CONFIG_MT76_LEDS)) mt76_led_cleanup(dev); + mt76_notifier_cleanup(dev); mt76_tx_status_check(dev, true); ieee80211_unregister_hw(hw); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 32a77a0ae9da..73a504016288 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -13,6 +13,7 @@ #include <linux/leds.h> #include <linux/usb.h> #include <linux/average.h> +#include <linux/reboot.h> #include <linux/soc/mediatek/mtk_wed.h> #include <net/mac80211.h> #include "util.h" @@ -835,6 +836,7 @@ struct mt76_dev { struct mt76_usb usb; struct mt76_sdio sdio; }; + struct notifier_block reboot_nb; }; struct mt76_power_limits {