diff mbox series

wifi: mt76: mt7921: retry dma-disable on startup.

Message ID 20230206193233.1716090-1-greearb@candelatech.com
State New
Headers show
Series wifi: mt76: mt7921: retry dma-disable on startup. | expand

Commit Message

Ben Greear Feb. 6, 2023, 7:32 p.m. UTC
From: Ben Greear <greearb@candelatech.com>

My system with lots of mtk7921k radios in it often fails to bring up
a few of them.  Adding a retry to the dma-disable logic appears to
fix the problem:

[   10.774941] mt7921e 0000:1d:00.0: ASIC revision: 79610010
[   10.776284] mt7921e 0000:1d:00.0: mt7921_dma_disable failed with timeout, force: 1
[   10.776285] mt7921e 0000:1d:00.0: mt7921_dma_disable failed: -110 (try 0/3)
[   10.778282] mt7921e 0000:1c:00.0: HW/SW Version: 0x8a108a10, Build Time: 20230117170855a
[   10.788427] mt7921e 0000:1c:00.0: WM Firmware Version: ____010000, Build Time: 20230117170942
[   10.852198] mt7921e 0000:1d:00.0: HW/SW Version: 0x8a108a10, Build Time: 20230117170855a
[   10.862222] mt7921e 0000:1d:00.0: WM Firmware Version: ____010000, Build Time: 20230117170942

Add additional logging to find other errors that could keep the radio from working
at all.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 .../net/wireless/mediatek/mt76/mt7921/dma.c   | 56 ++++++++++++++-----
 .../net/wireless/mediatek/mt76/mt7921/pci.c   | 34 ++++++++---
 2 files changed, 69 insertions(+), 21 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
index d1f10f6d9adc..54308ebbc39d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
@@ -92,8 +92,11 @@  static int mt7921_dma_disable(struct mt7921_dev *dev, bool force)
 
 	if (!mt76_poll(dev, MT_WFDMA0_GLO_CFG,
 		       MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
-		       MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000))
+		       MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000)) {
+		dev_info(dev->mt76.dev,
+			 "%s failed with timeout, force: %d", __func__, force);
 		return -ETIMEDOUT;
+	}
 
 	return 0;
 }
@@ -224,70 +227,97 @@  int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev)
 int mt7921_dma_init(struct mt7921_dev *dev)
 {
 	int ret;
+	int i;
 
 	mt76_dma_attach(&dev->mt76);
 
-	ret = mt7921_dma_disable(dev, true);
-	if (ret)
-		return ret;
+	for (i = 0; i < 3; i++) {
+		ret = mt7921_dma_disable(dev, true);
+		if (ret == 0)
+			break;
+		dev_info(dev->mt76.dev,
+			 "mt7921_dma_disable failed: %d (try %d/3)", ret, i);
+	}
+
+	if (ret < 0)
+		return ret; /* all dma disable retries failed */
 
 	ret = mt7921_wfsys_reset(dev);
-	if (ret)
+	if (ret) {
+		dev_info(dev->mt76.dev, "mt7921_wfsys_reset failed: %d", ret);
 		return ret;
+	}
 
 	/* init tx queue */
 	ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7921_TXQ_BAND0,
 					 MT7921_TX_RING_SIZE,
 					 MT_TX_RING_BASE, 0);
-	if (ret)
+	if (ret) {
+		dev_info(dev->mt76.dev, "mt76_connac_init_tx_queues failed: %d", ret);
 		return ret;
+	}
 
 	mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, 0x4);
 
 	/* command to WM */
 	ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7921_TXQ_MCU_WM,
 				  MT7921_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
-	if (ret)
+	if (ret) {
+		dev_info(dev->mt76.dev, "mt76_init_mcu_queue failed: %d", ret);
 		return ret;
+	}
 
 	/* firmware download */
 	ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7921_TXQ_FWDL,
 				  MT7921_TX_FWDL_RING_SIZE, MT_TX_RING_BASE);
-	if (ret)
+	if (ret) {
+		dev_info(dev->mt76.dev, "mt76_init_mcu_queue failed: %d", ret);
 		return ret;
+	}
 
 	/* event from WM before firmware download */
 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
 			       MT7921_RXQ_MCU_WM,
 			       MT7921_RX_MCU_RING_SIZE,
 			       MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE);
-	if (ret)
+	if (ret) {
+		dev_info(dev->mt76.dev, "mt76_queue_alloc failed: %d", ret);
 		return ret;
+	}
 
 	/* Change mcu queue after firmware download */
 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
 			       MT7921_RXQ_MCU_WM,
 			       MT7921_RX_MCU_RING_SIZE,
 			       MT_RX_BUF_SIZE, MT_WFDMA0(0x540));
-	if (ret)
+	if (ret) {
+		dev_info(dev->mt76.dev, "mt76_queue_alloc (after-fw-download) failed: %d", ret);
 		return ret;
+	}
 
 	/* rx data */
 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
 			       MT7921_RXQ_BAND0, MT7921_RX_RING_SIZE,
 			       MT_RX_BUF_SIZE, MT_RX_DATA_RING_BASE);
-	if (ret)
+	if (ret) {
+		dev_info(dev->mt76.dev, "mt76_queue_alloc (rx-data) failed: %d", ret);
 		return ret;
+	}
 
 	ret = mt76_init_queues(dev, mt7921_poll_rx);
-	if (ret < 0)
+	if (ret < 0) {
+		dev_info(dev->mt76.dev, "mt76_init_queues failed: %d", ret);
 		return ret;
+	}
 
 	netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi,
 			  mt7921_poll_tx);
 	napi_enable(&dev->mt76.tx_napi);
 
-	return mt7921_dma_enable(dev);
+	ret = mt7921_dma_enable(dev);
+	if (ret < 0)
+		dev_info(dev->mt76.dev, "mt7921_dma_enable failed: %d", ret);
+	return ret;
 }
 
 void mt7921_dma_cleanup(struct mt7921_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
index 7c923bb97c5d..e6e72c85c8d4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
@@ -262,22 +262,30 @@  static int mt7921_pci_probe(struct pci_dev *pdev,
 	int ret;
 
 	ret = pcim_enable_device(pdev);
-	if (ret)
+	if (ret) {
+		pr_info("pcim_enable_device failed: %d\n", ret);
 		return ret;
+	}
 
 	ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
-	if (ret)
+	if (ret) {
+		pr_info("pcim_iomap_regions failed: %d\n", ret);
 		return ret;
+	}
 
 	pci_set_master(pdev);
 
 	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
-	if (ret < 0)
+	if (ret < 0) {
+		pr_info("pci_alloc_irq_vectors failed: %d\n", ret);
 		return ret;
+	}
 
 	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret)
+	if (ret) {
+		pr_info("dma_set_mask failed: %d\n", ret);
 		goto err_free_pci_vec;
+	}
 
 	if (mt7921_disable_aspm)
 		mt76_pci_disable_aspm(pdev);
@@ -285,6 +293,7 @@  static int mt7921_pci_probe(struct pci_dev *pdev,
 	mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7921_ops,
 				 &drv_ops);
 	if (!mdev) {
+		pr_info("mt76_alloc_device failed (ENOMEM?)\n");
 		ret = -ENOMEM;
 		goto err_free_pci_vec;
 	}
@@ -304,6 +313,7 @@  static int mt7921_pci_probe(struct pci_dev *pdev,
 	bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops),
 			       GFP_KERNEL);
 	if (!bus_ops) {
+		dev_info(mdev->dev, "devm_kmemdup bus-opps failed (ENOMEM?)\n");
 		ret = -ENOMEM;
 		goto err_free_dev;
 	}
@@ -314,8 +324,10 @@  static int mt7921_pci_probe(struct pci_dev *pdev,
 	dev->mt76.bus = bus_ops;
 
 	ret = __mt7921e_mcu_drv_pmctrl(dev);
-	if (ret)
+	if (ret) {
+		dev_info(mdev->dev, "__mt7921e_mcu_drv_pmctrl failed: %d\n", ret);
 		goto err_free_dev;
+	}
 
 	mdev->rev = (mt7921_l1_rr(dev, MT_HW_CHIPID) << 16) |
 		    (mt7921_l1_rr(dev, MT_HW_REV) & 0xff);
@@ -327,16 +339,22 @@  static int mt7921_pci_probe(struct pci_dev *pdev,
 
 	ret = devm_request_irq(mdev->dev, pdev->irq, mt7921_irq_handler,
 			       IRQF_SHARED, KBUILD_MODNAME, dev);
-	if (ret)
+	if (ret) {
+		dev_info(mdev->dev, "devm_request_irq failed: %d\n", ret);
 		goto err_free_dev;
+	}
 
 	ret = mt7921_dma_init(dev);
-	if (ret)
+	if (ret) {
+		dev_info(mdev->dev, "mt7921_dma_init failed: %d\n", ret);
 		goto err_free_irq;
+	}
 
 	ret = mt7921_register_device(dev);
-	if (ret)
+	if (ret) {
+		dev_info(mdev->dev, "mt7921_register_device failed failed: %d\n", ret);
 		goto err_free_irq;
+	}
 
 	return 0;