diff mbox series

wifi: mt76: mt7921e: introduce reboot notifier support

Message ID 28482de35c4f1589dcf96b662a48bc558fe46e8f.1669361180.git.deren.wu@mediatek.com (mailing list archive)
State Superseded
Delegated to: Felix Fietkau
Headers show
Series wifi: mt76: mt7921e: introduce reboot notifier support | expand

Commit Message

Deren Wu Nov. 25, 2022, 7:36 a.m. UTC
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>
---
 .../wireless/mediatek/mt76/mt7921/mt7921.h    |  1 +
 .../net/wireless/mediatek/mt76/mt7921/pci.c   | 25 +++++++++++++++++++
 2 files changed, 26 insertions(+)

Comments

Felix Fietkau Nov. 28, 2022, 9:26 a.m. UTC | #1
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
Deren Wu Nov. 29, 2022, 1:11 a.m. UTC | #2
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
Ryder Lee Nov. 29, 2022, 2:21 a.m. UTC | #3
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 mbox series

Patch

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: