Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 02/18] wifi: mt76: mt7925: add MT7927 firmware paths and PCI device IDs
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

Add PCI device IDs for MT7927 (14c3:7927) and MT7927 (14c3:6639)
hardware variants, along with firmware path definitions for the MT7927
WiFi firmware.

Known hardware using these IDs:

  - ASUS ROG Crosshair X870E Hero (14c3:7927)
  - Lenovo Legion Pro 7 16ARX9 (14c3:7927)
  - Foxconn/Azurewave modules (14c3:6639)
  - AMD RZ738 (MediaTek MT7927) (14c3:0738)

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c | 6 ++++++
 drivers/net/wireless/mediatek/mt76/mt792x.h     | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index c4161754c01d..54eac5c6e509 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -16,6 +16,10 @@ static const struct pci_device_id mt7925_pci_device_table[] = {
 		.driver_data = (kernel_ulong_t)MT7925_FIRMWARE_WM },
 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0717),
 		.driver_data = (kernel_ulong_t)MT7925_FIRMWARE_WM },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7927),
+		.driver_data = (kernel_ulong_t)MT7927_FIRMWARE_WM },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x6639),
+		.driver_data = (kernel_ulong_t)MT7927_FIRMWARE_WM },
 	{ },
 };
 
@@ -633,6 +637,8 @@ module_pci_driver(mt7925_pci_driver);
 MODULE_DEVICE_TABLE(pci, mt7925_pci_device_table);
 MODULE_FIRMWARE(MT7925_FIRMWARE_WM);
 MODULE_FIRMWARE(MT7925_ROM_PATCH);
+MODULE_FIRMWARE(MT7927_FIRMWARE_WM);
+MODULE_FIRMWARE(MT7927_ROM_PATCH);
 MODULE_AUTHOR("Deren Wu <deren.wu@mediatek.com>");
 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
 MODULE_DESCRIPTION("MediaTek MT7925E (PCIe) wireless driver");
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h
index 8388638ed550..38790ef83e51 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x.h
@@ -45,11 +45,13 @@
 #define MT7921_FIRMWARE_WM	"mediatek/WIFI_RAM_CODE_MT7961_1.bin"
 #define MT7922_FIRMWARE_WM	"mediatek/WIFI_RAM_CODE_MT7922_1.bin"
 #define MT7925_FIRMWARE_WM	"mediatek/mt7925/WIFI_RAM_CODE_MT7925_1_1.bin"
+#define MT7927_FIRMWARE_WM	"mediatek/mt7927/WIFI_RAM_CODE_MT6639_2_1.bin"
 
 #define MT7920_ROM_PATCH	"mediatek/WIFI_MT7961_patch_mcu_1a_2_hdr.bin"
 #define MT7921_ROM_PATCH	"mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin"
 #define MT7922_ROM_PATCH	"mediatek/WIFI_MT7922_patch_mcu_1_1_hdr.bin"
 #define MT7925_ROM_PATCH	"mediatek/mt7925/WIFI_MT7925_PATCH_MCU_1_1_hdr.bin"
+#define MT7927_ROM_PATCH	"mediatek/mt7927/WIFI_MT6639_PATCH_MCU_2_1_hdr.bin"
 
 #define MT792x_SDIO_HDR_TX_BYTES	GENMASK(15, 0)
 #define MT792x_SDIO_HDR_PKT_TYPE	GENMASK(17, 16)
@@ -454,6 +456,8 @@ static inline char *mt792x_ram_name(struct mt792x_dev *dev)
 		return MT7922_FIRMWARE_WM;
 	case 0x7925:
 		return MT7925_FIRMWARE_WM;
+	case 0x7927:
+		return MT7927_FIRMWARE_WM;
 	default:
 		return MT7921_FIRMWARE_WM;
 	}
@@ -468,6 +472,8 @@ static inline char *mt792x_patch_name(struct mt792x_dev *dev)
 		return MT7922_ROM_PATCH;
 	case 0x7925:
 		return MT7925_ROM_PATCH;
+	case 0x7927:
+		return MT7927_ROM_PATCH;
 	default:
 		return MT7921_ROM_PATCH;
 	}

-- 
2.53.0


^ permalink raw reply related

* [PATCH 03/18] wifi: mt76: mt7925: add MT7927 CBTOP remap and chip initialization
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

The MT7927 combo chip has an additional bus fabric called CBInfra
(ConnectaBus Infrastructure) between PCIe and the WiFi subsystem.
Without configuring the CBTOP address remap, all MMIO reads to WiFi
registers return zero.

Add mt7927_cbtop_remap() to configure the PCIe address mapping for WiFi
and Bluetooth subsystems, and mt7927_chip_init() to perform the CBInfra
initialization sequence:

  1. EMI sleep protect enable
  2. WF subsystem reset via CBInfra RGU
  3. MCU ownership acquisition
  4. Poll ROMCODE_INDEX for MCU idle (0x1D1E)
  5. MCIF remap for host DMA
  6. PCIe sleep disable

Skip the early CLR_OWN in probe for MT7927 since CBTOP remap is not yet
configured at that point - the ROM's WFDMA init would fail.

Register values derived from Loong0x00's reverse-engineered MT7927
driver.

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c  | 90 ++++++++++++++++++++++--
 drivers/net/wireless/mediatek/mt76/mt792x_regs.h | 18 +++++
 2 files changed, 101 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index 54eac5c6e509..c16ec05c5601 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -270,6 +270,60 @@ static int mt7925_dma_init(struct mt792x_dev *dev)
 	return mt792x_dma_enable(dev);
 }
 
+static int mt7927_chip_init(struct mt792x_dev *dev)
+{
+	struct mt76_dev *mdev = &dev->mt76;
+	u32 val;
+
+	/* EMI sleep protect */
+	mt76_rmw_field(dev, MT_HW_EMI_CTL, MT_HW_EMI_CTL_SLPPROT_EN, 1);
+
+	/* WF subsystem reset via CBInfra RGU */
+	mt76_set(dev, MT_CBINFRA_RGU_WF_RST, MT_CBINFRA_RGU_WF_RST_WF_SUBSYS);
+	msleep(1);
+	mt76_clear(dev, MT_CBINFRA_RGU_WF_RST,
+		   MT_CBINFRA_RGU_WF_RST_WF_SUBSYS);
+	msleep(5);
+
+	/* MCU ownership */
+	mt76_wr(dev, MT_CBINFRA_MCU_OWN_SET, BIT(0));
+
+	/* Poll ROMCODE_INDEX for MCU idle */
+	if (!__mt76_poll_msec(mdev, MT_ROMCODE_INDEX,
+			      0xffff, MT_MCU_IDLE_VALUE, 2000)) {
+		val = mt76_rr(dev, MT_ROMCODE_INDEX);
+		dev_err(mdev->dev,
+			"MT7927 MCU idle timeout (ROMCODE_INDEX=0x%04x)\n",
+			val & 0xffff);
+		return -ETIMEDOUT;
+	}
+
+	/* MCIF remap - MCU needs this to DMA to host memory */
+	mt76_wr(dev, MT_MCIF_REMAP_WF_1_BA, MT_MCIF_REMAP_WF_1_BA_VAL);
+
+	/* Disable PCIe sleep */
+	mt76_wr(dev, MT_CBINFRA_SLP_CTRL, 0xffffffff);
+
+	/* Clear CONNINFRA wakeup */
+	mt76_wr(dev, MT_CBINFRA_WAKEPU_TOP, 0x0);
+
+	return 0;
+}
+
+static void mt7927_cbtop_remap(struct mt792x_dev *dev)
+{
+	/* CONNINFRA wakeup - required before CBInfra register access */
+	mt76_wr(dev, MT_CBINFRA_WAKEPU_TOP, 0x1);
+	usleep_range(1000, 2000);
+
+	/* Configure CBTOP PCIe address remap for WF and BT */
+	mt76_wr(dev, MT_CBINFRA_MISC0_REMAP_WF, MT_CBINFRA_REMAP_WF_VAL);
+	mt76_wr(dev, MT_CBINFRA_MISC0_REMAP_BT, MT_CBINFRA_REMAP_BT_VAL);
+
+	/* Readback to push writes */
+	mt76_rr(dev, MT_CBINFRA_MISC0_REMAP_WF);
+}
+
 static int mt7925_pci_probe(struct pci_dev *pdev,
 			    const struct pci_device_id *id)
 {
@@ -314,6 +368,7 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	struct mt76_bus_ops *bus_ops;
 	struct mt792x_dev *dev;
 	struct mt76_dev *mdev;
+	bool is_mt7927_hw;
 	u8 features;
 	int ret;
 	u16 cmd;
@@ -385,24 +440,45 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	if (!mt7925_disable_aspm && mt76_pci_aspm_supported(pdev))
 		dev->aspm_supported = true;
 
+	is_mt7927_hw = (pdev->device == 0x6639 || pdev->device == 0x7927);
+
 	ret = __mt792x_mcu_fw_pmctrl(dev);
 	if (ret)
 		goto err_free_dev;
 
-	ret = __mt792xe_mcu_drv_pmctrl(dev);
-	if (ret)
-		goto err_free_dev;
+	if (!is_mt7927_hw) {
+		ret = __mt792xe_mcu_drv_pmctrl(dev);
+		if (ret)
+			goto err_free_dev;
+	}
+
+	if (is_mt7927_hw)
+		mt7927_cbtop_remap(dev);
 
 	mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
 		    (mt76_rr(dev, MT_HW_REV) & 0xff);
 
 	dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
 
-	mt76_rmw_field(dev, MT_HW_EMI_CTL, MT_HW_EMI_CTL_SLPPROT_EN, 1);
+	/* Force chip ID for MT7927 hardware if CHIPID read returns garbage */
+	if (is_mt7927_hw && (mdev->rev >> 16) != 0x7927) {
+		dev_info(mdev->dev,
+			 "MT7927 raw CHIPID=0x%04x, forcing chip=0x7927\n",
+			 (u16)(mdev->rev >> 16));
+		mdev->rev = (0x7927 << 16) | (mdev->rev & 0xff);
+	}
 
-	ret = mt792x_wfsys_reset(dev);
-	if (ret)
-		goto err_free_dev;
+	if (is_mt7927_hw) {
+		ret = mt7927_chip_init(dev);
+		if (ret)
+			goto err_free_dev;
+	} else {
+		mt76_rmw_field(dev, MT_HW_EMI_CTL,
+			       MT_HW_EMI_CTL_SLPPROT_EN, 1);
+		ret = mt792x_wfsys_reset(dev);
+		if (ret)
+			goto err_free_dev;
+	}
 
 	mt76_wr(dev, irq_map.host_irq_enable, 0);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
index acf627aed609..0f75dca0a96c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
@@ -484,4 +484,22 @@
 #define WFSYS_SW_RST_B			BIT(0)
 #define WFSYS_SW_INIT_DONE		BIT(4)
 
+/* CBInfra registers - MT7927 combo chip */
+#define MT_CBINFRA_WAKEPU_TOP		0xe01a0
+#define MT_CBINFRA_MISC0_REMAP_WF	0x1f6554
+#define MT_CBINFRA_MISC0_REMAP_BT	0x1f6558
+#define MT_CBINFRA_RGU_WF_RST		0x1f8600
+#define MT_CBINFRA_RGU_WF_RST_WF_SUBSYS	BIT(4)
+#define MT_CBINFRA_MCU_OWN_SET		0x1f5034
+#define MT_CBINFRA_SLP_CTRL		0x1f5018
+#define MT_ROMCODE_INDEX		0xc1604
+#define MT_MCU_IDLE_VALUE		0x1d1e
+#define MT_MCIF_REMAP_WF_1_BA		0xd1034
+
+/* CBInfra CBTOP remap values */
+#define MT_CBINFRA_REMAP_WF_VAL	0x74037001
+#define MT_CBINFRA_REMAP_BT_VAL	0x70007000
+
+#define MT_MCIF_REMAP_WF_1_BA_VAL	0x18051803
+
 #endif /* __MT792X_REGS_H */

-- 
2.53.0


^ permalink raw reply related

* [PATCH 04/18] wifi: mt76: mt7925: add MT7927 DMA ring layout, IRQ map, and prefetch
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

MT7927 uses different DMA ring indices than MT7925:

  - RX MCU events: ring 6 (MT7925 uses ring 0)
  - RX data: ring 4 (MT7925 uses ring 2)
  - RX auxiliary: ring 7 (management frames)
  - TX rings are identical

Add mt7927_dma_init() with the correct ring allocation, a dedicated
mt7927_irq_map with matching interrupt enable bits (BIT(12), BIT(14),
BIT(15) for RX rings 4, 6, 7), and MT7927 packed prefetch register
configuration in mt792x_dma_prefetch().

The DMA init performs a controlled SET_OWN/CLR_OWN sequence after CBTOP
and CBInfra initialization, since CLR_OWN triggers the ROM to initialize
WFDMA.

Ring layout and prefetch values derived from Loong0x00's
reverse-engineered MT7927 driver.

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h |   7 ++
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c    | 131 ++++++++++++++++++++-
 drivers/net/wireless/mediatek/mt76/mt792x_dma.c    |  18 ++-
 drivers/net/wireless/mediatek/mt76/mt792x_regs.h   |  10 ++
 4 files changed, 163 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
index 6b9bf1b89032..ba3d2c4de4ce 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
@@ -126,6 +126,13 @@ enum mt7925_rxq_id {
 	MT7925_RXQ_MCU_WM2, /* for tx done */
 };
 
+/* MT7927 uses different RX ring indices than MT7925 */
+enum mt7927_rxq_id {
+	MT7927_RXQ_BAND0 = 4,
+	MT7927_RXQ_MCU_WM = 6,
+	MT7927_RXQ_DATA2 = 7,
+};
+
 enum {
 	MODE_OPEN = 0,
 	MODE_SHARED = 1,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index c16ec05c5601..ca9ccfe9975c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -324,6 +324,127 @@ static void mt7927_cbtop_remap(struct mt792x_dev *dev)
 	mt76_rr(dev, MT_CBINFRA_MISC0_REMAP_WF);
 }
 
+static int mt7927_dma_init(struct mt792x_dev *dev)
+{
+	int ret;
+
+	mt76_dma_attach(&dev->mt76);
+
+	/* Do SET_OWN -> CLR_OWN now that CBTOP and CBInfra are ready.
+	 * CLR_OWN triggers the ROM to initialize WFDMA properly. */
+	ret = mt792xe_mcu_fw_pmctrl(dev);
+	if (ret)
+		return ret;
+
+	ret = __mt792xe_mcu_drv_pmctrl(dev);
+	if (ret)
+		return ret;
+
+	/* Clear pending interrupts from previous state */
+	mt76_wr(dev, MT_WFDMA0_HOST_INT_STA, ~0);
+
+	/* Disable DMA */
+	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
+		   MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+		   MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+		   MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
+		   MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+	wmb();
+
+	if (!mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG,
+				 MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
+				 MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1))
+		return -ETIMEDOUT;
+
+	/* Reset DMA descriptor pointers */
+	mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
+	mt76_wr(dev, MT_WFDMA0_RST_DRX_PTR, ~0);
+	wmb();
+	msleep(10);
+
+	/* init tx queue - ring 0 */
+	ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7925_TXQ_BAND0,
+					 MT7925_TX_RING_SIZE,
+					 MT_TX_RING_BASE, NULL, 0);
+	if (ret)
+		return ret;
+
+	mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, 0x4);
+
+	/* command to WM - ring 15 */
+	ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM,
+				  MT7925_TXQ_MCU_WM,
+				  MT7925_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
+	if (ret)
+		return ret;
+
+	/* firmware download - ring 16 */
+	ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL,
+				  MT7925_TXQ_FWDL,
+				  MT7925_TX_FWDL_RING_SIZE, MT_TX_RING_BASE);
+	if (ret)
+		return ret;
+
+	/* rx MCU events - ring 6 (MT7925 uses ring 0) */
+	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
+			       MT7927_RXQ_MCU_WM, MT7925_RX_MCU_RING_SIZE,
+			       MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE);
+	if (ret)
+		return ret;
+
+	/* rx data - ring 4 (MT7925 uses ring 2) */
+	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
+			       MT7927_RXQ_BAND0, MT7925_RX_RING_SIZE,
+			       MT_RX_BUF_SIZE, MT_RX_DATA_RING_BASE);
+	if (ret)
+		return ret;
+
+	/* rx auxiliary - ring 7: management frames */
+	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
+			       MT7927_RXQ_DATA2, MT7925_RX_MCU_RING_SIZE,
+			       MT_RX_BUF_SIZE, MT_RX_DATA_RING_BASE);
+	if (ret)
+		return ret;
+
+	ret = mt76_init_queues(dev, mt792x_poll_rx);
+	if (ret < 0)
+		return ret;
+
+	netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi,
+			  mt792x_poll_tx);
+	napi_enable(&dev->mt76.tx_napi);
+
+	/* MT7927-specific GLO_CFG bits before DMA enable */
+	mt76_set(dev, MT_WFDMA0_GLO_CFG, BIT(26));   /* ADDR_EXT_EN */
+	mt76_clear(dev, MT_WFDMA0_GLO_CFG, BIT(20)); /* CSR_LBK_RX_Q_SEL_EN */
+	mt76_set(dev, MT_WFDMA0_GLO_CFG_EXT1, BIT(28));
+	mt76_set(dev, MT_WFDMA0_GLO_CFG,
+		 MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL);
+
+	ret = mt792x_dma_enable(dev);
+	if (ret)
+		return ret;
+
+	/* Enable interrupts synchronously */
+	mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, dev->mt76.mmio.irqmask);
+
+	return 0;
+}
+
+static const struct mt792x_irq_map mt7927_irq_map = {
+	.host_irq_enable = MT_WFDMA0_HOST_INT_ENA,
+	.tx = {
+		.all_complete_mask = MT_INT_TX_DONE_ALL,
+		.mcu_complete_mask = MT_INT_TX_DONE_MCU,
+	},
+	.rx = {
+		.data_complete_mask = HOST_RX_DONE_INT_ENA4,
+		.wm_complete_mask = HOST_RX_DONE_INT_ENA6,
+		.wm2_complete_mask = HOST_RX_DONE_INT_ENA7,
+	},
+};
+
 static int mt7925_pci_probe(struct pci_dev *pdev,
 			    const struct pci_device_id *id)
 {
@@ -417,7 +538,10 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	dev = container_of(mdev, struct mt792x_dev, mt76);
 	dev->fw_features = features;
 	dev->hif_ops = &mt7925_pcie_ops;
-	dev->irq_map = &irq_map;
+	if (is_mt7927_hw)
+		dev->irq_map = &mt7927_irq_map;
+	else
+		dev->irq_map = &irq_map;
 	mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);
 	tasklet_init(&mdev->irq_tasklet, mt792x_irq_tasklet, (unsigned long)dev);
 
@@ -489,7 +613,10 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	if (ret)
 		goto err_free_dev;
 
-	ret = mt7925_dma_init(dev);
+	if (is_mt7927_hw)
+		ret = mt7927_dma_init(dev);
+	else
+		ret = mt7925_dma_init(dev);
 	if (ret)
 		goto err_free_irq;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
index 1ddec7788b66..3177c6cc6eb5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
@@ -90,7 +90,23 @@ EXPORT_SYMBOL_GPL(mt792x_rx_poll_complete);
 #define PREFETCH(base, depth)	((base) << 16 | (depth))
 static void mt792x_dma_prefetch(struct mt792x_dev *dev)
 {
-	if (is_mt7925(&dev->mt76)) {
+	if (is_mt7927(&dev->mt76)) {
+		/* Trigger prefetch controller reset before reprogramming */
+		mt76_wr(dev, MT_WFDMA_PREFETCH_CTRL,
+			mt76_rr(dev, MT_WFDMA_PREFETCH_CTRL));
+		/* MT7927 uses packed prefetch registers */
+		mt76_wr(dev, MT_WFDMA_PREFETCH_CFG0, 0x660077);
+		mt76_wr(dev, MT_WFDMA_PREFETCH_CFG1, 0x1100);
+		mt76_wr(dev, MT_WFDMA_PREFETCH_CFG2, 0x30004f);
+		mt76_wr(dev, MT_WFDMA_PREFETCH_CFG3, 0x542200);
+		/* per-ring EXT_CTRL */
+		mt76_wr(dev, MT_WFDMA0_RX_RING4_EXT_CTRL, PREFETCH(0x0000, 0x8));
+		mt76_wr(dev, MT_WFDMA0_RX_RING6_EXT_CTRL, PREFETCH(0x0080, 0x8));
+		mt76_wr(dev, MT_WFDMA0_RX_RING7_EXT_CTRL, PREFETCH(0x0100, 0x4));
+		mt76_wr(dev, MT_WFDMA0_TX_RING16_EXT_CTRL, PREFETCH(0x0140, 0x4));
+		mt76_wr(dev, MT_WFDMA0_TX_RING15_EXT_CTRL, PREFETCH(0x0180, 0x10));
+		mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, PREFETCH(0x0280, 0x4));
+	} else if (is_mt7925(&dev->mt76)) {
 		/* rx ring */
 		mt76_wr(dev, MT_WFDMA0_RX_RING0_EXT_CTRL, PREFETCH(0x0000, 0x4));
 		mt76_wr(dev, MT_WFDMA0_RX_RING1_EXT_CTRL, PREFETCH(0x0040, 0x4));
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
index 0f75dca0a96c..5497cfaab8d7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
@@ -363,6 +363,16 @@
 #define MT_WFDMA_EXT_CSR_HIF_MISC	MT_WFDMA_EXT_CSR(0x44)
 #define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY	BIT(0)
 
+/* MT7927 packed prefetch registers */
+#define MT_WFDMA_PREFETCH_CTRL		MT_WFDMA_EXT_CSR(0x30)
+#define MT_WFDMA_PREFETCH_CFG0		MT_WFDMA_EXT_CSR(0xf0)
+#define MT_WFDMA_PREFETCH_CFG1		MT_WFDMA_EXT_CSR(0xf4)
+#define MT_WFDMA_PREFETCH_CFG2		MT_WFDMA_EXT_CSR(0xf8)
+#define MT_WFDMA_PREFETCH_CFG3		MT_WFDMA_EXT_CSR(0xfc)
+
+/* MT7927 GLO_CFG extended register */
+#define MT_WFDMA0_GLO_CFG_EXT1		MT_WFDMA0(0x2b4)
+
 #define MT_SWDEF_BASE			0x41f200
 #define MT_SWDEF(ofs)			(MT_SWDEF_BASE + (ofs))
 #define MT_SWDEF_MODE			MT_SWDEF(0x3c)

-- 
2.53.0


^ permalink raw reply related

* [PATCH 05/18] wifi: mt76: mt7925: skip CLR_OWN in mt7925e_mcu_init for MT7927
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

On MT7927 hardware, every CLR_OWN triggers the ROM bootloader to
reinitialize the WFDMA engine, destroying all DMA ring configuration
(base addresses, prefetch settings, descriptor pointers).

The DMA rings are already properly initialized by mt7927_dma_init()
which performs a controlled CLR_OWN before ring setup. Skip the
SET_OWN/CLR_OWN cycle in mt7925e_mcu_init() to preserve that
configuration.

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/pci_mcu.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci_mcu.c
index 6cceff88c656..206d525eb550 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci_mcu.c
@@ -35,13 +35,20 @@ int mt7925e_mcu_init(struct mt792x_dev *dev)
 
 	dev->mt76.mcu_ops = &mt7925_mcu_ops;
 
-	err = mt792xe_mcu_fw_pmctrl(dev);
-	if (err)
-		return err;
+	if (is_mt7927(&dev->mt76)) {
+		/* MT7927: CLR_OWN was already done in mt7927_dma_init().
+		 * The ROM re-initializes WFDMA on every CLR_OWN, wiping
+		 * ring and prefetch config. Skip SET_OWN/CLR_OWN here
+		 * to preserve DMA state. */
+	} else {
+		err = mt792xe_mcu_fw_pmctrl(dev);
+		if (err)
+			return err;
 
-	err = __mt792xe_mcu_drv_pmctrl(dev);
-	if (err)
-		return err;
+		err = __mt792xe_mcu_drv_pmctrl(dev);
+		if (err)
+			return err;
+	}
 
 	mt76_rmw_field(dev, MT_PCIE_MAC_PM, MT_PCIE_MAC_PM_L0S_DIS, 1);
 

-- 
2.53.0


^ permalink raw reply related

* [PATCH 06/18] wifi: mt76: mt7925: add MT7927 power management, DBDC, and CNM fixes
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

Three MT7927-specific fixes for WiFi functionality:

1. Disable runtime PM: Every CLR_OWN triggers the ROM to reinitialize
   WFDMA, destroying DMA ring configuration. Disable PM until the wake
   path properly handles MT7927.

2. Enable DBDC (dual-band): MT7927 firmware defaults to single-band
   (2.4GHz only). MT7925 firmware handles DBDC automatically, but
   MT7927 requires an explicit MCU_UNI_CMD(SET_DBDC_PARMS) with
   mbmc_en=1. Without this, 5GHz scan requests are silently discarded.

3. Force CNM capability: MT7927 firmware lacks the connac2 feature
   trailer, causing mt792x_get_mac80211_ops() to replace channel
   context operations with emulated stubs. This prevents ROC (remain
   on channel) before authentication, causing auth frames to be
   silently dropped. Force the CNM flag and restore mt7925_ops.

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/init.c | 17 ++++++++++++++++-
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c  | 10 ++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c
index 3ce5d6fcc69d..1e9eadca3988 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c
@@ -115,6 +115,18 @@ static int __mt7925_init_hardware(struct mt792x_dev *dev)
 	if (ret)
 		goto out;
 
+	/* MT7927: Enable DBDC (dual-band) mode. Without this, firmware
+	 * defaults to 2.4GHz only and ignores 5GHz scan requests.
+	 * MT7925 firmware handles DBDC automatically. */
+	if (is_mt7927(&dev->mt76)) {
+		ret = mt7925_mcu_set_dbdc(&dev->mphy, true);
+		if (ret) {
+			dev_warn(dev->mt76.dev,
+				 "MT7927 DBDC enable failed: %d\n", ret);
+			ret = 0;
+		}
+	}
+
 out:
 	return ret;
 }
@@ -230,7 +242,10 @@ int mt7925_register_device(struct mt792x_dev *dev)
 	dev->pm.idle_timeout = MT792x_PM_TIMEOUT;
 	dev->pm.stats.last_wake_event = jiffies;
 	dev->pm.stats.last_doze_event = jiffies;
-	if (!mt76_is_usb(&dev->mt76)) {
+	/* MT7927: disable power management. Every CLR_OWN triggers the
+	 * ROM to reinitialize WFDMA, destroying DMA ring configuration.
+	 * Keep the device awake until the PM wake path handles MT7927. */
+	if (!mt76_is_usb(&dev->mt76) && !is_mt7927(&dev->mt76)) {
 		dev->pm.enable_user = true;
 		dev->pm.enable = true;
 		dev->pm.ds_enable_user = true;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index ca9ccfe9975c..dce9f30b68d7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -527,6 +527,16 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 		goto err_free_pci_vec;
 	}
 
+	/* MT7927 firmware lacks the connac2 feature trailer, so
+	 * mt792x_get_mac80211_ops() can't detect CNM support and
+	 * replaces chanctx/ROC/mgd_prepare_tx ops with stubs.
+	 * Force CNM and restore the original mt7925 ops. */
+	if ((pdev->device == 0x6639 || pdev->device == 0x7927) &&
+	    !(features & MT792x_FW_CAP_CNM)) {
+		features |= MT792x_FW_CAP_CNM;
+		memcpy(ops, &mt7925_ops, sizeof(*ops));
+	}
+
 	mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), ops, &drv_ops);
 	if (!mdev) {
 		ret = -ENOMEM;

-- 
2.53.0


^ permalink raw reply related

* [PATCH 07/18] wifi: mt76: mt7925: use irq_map fields instead of MT_INT_RX_DONE_ALL
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

The mac_reset and resume paths use the hardcoded MT_INT_RX_DONE_ALL
constant (bits 0-2) to re-enable RX interrupts. This is correct for
MT7925 (RX rings 0, 1, 2) but wrong for MT7927 which uses RX rings 4, 6,
7 (bits 12, 14, 15).

Replace with the per-chip irq_map fields so the correct interrupt bits
are enabled regardless of the chip variant.

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c     | 5 ++++-
 drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c | 5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index dce9f30b68d7..0dec25b320f8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -766,7 +766,10 @@ static int _mt7925_pci_resume(struct device *device, bool restore)
 	mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
 	mt76_connac_irq_enable(&dev->mt76,
 			       dev->irq_map->tx.all_complete_mask |
-			       MT_INT_RX_DONE_ALL | MT_INT_MCU_CMD);
+			       dev->irq_map->rx.data_complete_mask |
+			       dev->irq_map->rx.wm_complete_mask |
+			       dev->irq_map->rx.wm2_complete_mask |
+			       MT_INT_MCU_CMD);
 	mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE);
 
 	/* put dma enabled */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c
index 3072850c2752..1626a3684082 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c
@@ -118,7 +118,10 @@ int mt7925e_mac_reset(struct mt792x_dev *dev)
 
 	mt76_wr(dev, dev->irq_map->host_irq_enable,
 		dev->irq_map->tx.all_complete_mask |
-		MT_INT_RX_DONE_ALL | MT_INT_MCU_CMD);
+		dev->irq_map->rx.data_complete_mask |
+		dev->irq_map->rx.wm_complete_mask |
+		dev->irq_map->rx.wm2_complete_mask |
+		MT_INT_MCU_CMD);
 	mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
 
 	err = mt792xe_mcu_fw_pmctrl(dev);

-- 
2.53.0


^ permalink raw reply related

* [PATCH 08/18] wifi: mt76: mt7925: guard mac_reset against MT7927 DMA destruction
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

On MT7927 hardware, the mac_reset path performs CLR_OWN and WPDMA logic
reset, both of which destroy DMA ring configuration. CLR_OWN triggers
the ROM to reinitialize WFDMA, and the logic reset pulse disrupts the
WFDMA state that mt7927_dma_init() carefully configured.

A full MT7927 reset requires re-running the DMA initialization sequence,
which is not yet implemented in the recovery path. Return -EOPNOTSUPP
with a warning so users know to reload the module.

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c
index 1626a3684082..cf578a2cdc68 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c
@@ -72,6 +72,14 @@ int mt7925e_mac_reset(struct mt792x_dev *dev)
 	const struct mt792x_irq_map *irq_map = dev->irq_map;
 	int i, err;
 
+	/* MT7927: CLR_OWN and WPDMA reset destroy DMA ring configuration.
+	 * A full reset requires re-running mt7927_dma_init() which is not
+	 * yet implemented in the recovery path. */
+	if (is_mt7927(&dev->mt76)) {
+		dev_warn(dev->mt76.dev, "MT7927 mac_reset not supported, reload module to recover\n");
+		return -EOPNOTSUPP;
+	}
+
 	mt792xe_mcu_drv_pmctrl(dev);
 
 	mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);

-- 
2.53.0


^ permalink raw reply related

* [PATCH 09/18] wifi: mt76: mt7925: populate EHT 320MHz MCS map in sta_rec
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

The sta_rec_eht structure has a mcs_map_bw320 field, and the channel
width mapping includes NL80211_CHAN_WIDTH_320, but the 320MHz MCS/NSS
map was never copied from the station's EHT capabilities to the MCU TLV.
This prevents negotiation of 320MHz channel width even when both the
hardware and firmware advertise support for it.

Add the missing memcpy for the 320MHz MCS map, matching the existing
pattern for BW20, BW80, and BW160.

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index cf0fdea45cf7..8b5ffb240d52 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -1683,6 +1683,7 @@ mt7925_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_link_sta *link_sta)
 		memcpy(eht->mcs_map_bw20, &mcs_map->only_20mhz, sizeof(eht->mcs_map_bw20));
 	memcpy(eht->mcs_map_bw80, &mcs_map->bw._80, sizeof(eht->mcs_map_bw80));
 	memcpy(eht->mcs_map_bw160, &mcs_map->bw._160, sizeof(eht->mcs_map_bw160));
+	memcpy(eht->mcs_map_bw320, &mcs_map->bw._320, sizeof(eht->mcs_map_bw320));
 }
 
 static void

-- 
2.53.0


^ permalink raw reply related

* [PATCH 10/18] wifi: mt76: mt7925: enable MT7927 runtime power management
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

Add MT7927-specific GLO_CFG register programming to mt792x_dma_enable()
so that ADDR_EXT_EN and CSR_LBK_RX_Q_SEL_EN are correctly configured
after every WPDMA reinitialization triggered by CLR_OWN during power
management transitions.

On MT7927, every CLR_OWN causes the ROM to reinitialize WFDMA, which
resets the DMA configuration. The PM wake path already handles ring
reprogramming (mt76_queue_reset restores ring base addresses from
stored desc_dma) and prefetch configuration (mt792x_dma_prefetch has
an is_mt7927 branch), but two GLO_CFG bits were missing from
mt792x_dma_enable:

  - BIT(26) ADDR_EXT_EN: extended DMA addressing, required for
    MT7927's host memory access
  - BIT(20) CSR_LBK_RX_Q_SEL_EN: loopback RX queue select, must
    be cleared for normal DMA operation

Also define proper macros for these bits and use them in
mt7927_dma_init() to replace bare BIT() values.

With the DMA recovery path now fully MT7927-aware, remove the
is_mt7927() guard that disabled runtime PM and deep sleep. Let the
standard mt792x power management work for MT7927 hardware.

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/init.c | 5 +----
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c  | 4 ++--
 drivers/net/wireless/mediatek/mt76/mt792x_dma.c  | 7 +++++++
 drivers/net/wireless/mediatek/mt76/mt792x_regs.h | 2 ++
 4 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c
index 1e9eadca3988..84af52a0176d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c
@@ -242,10 +242,7 @@ int mt7925_register_device(struct mt792x_dev *dev)
 	dev->pm.idle_timeout = MT792x_PM_TIMEOUT;
 	dev->pm.stats.last_wake_event = jiffies;
 	dev->pm.stats.last_doze_event = jiffies;
-	/* MT7927: disable power management. Every CLR_OWN triggers the
-	 * ROM to reinitialize WFDMA, destroying DMA ring configuration.
-	 * Keep the device awake until the PM wake path handles MT7927. */
-	if (!mt76_is_usb(&dev->mt76) && !is_mt7927(&dev->mt76)) {
+	if (!mt76_is_usb(&dev->mt76)) {
 		dev->pm.enable_user = true;
 		dev->pm.enable = true;
 		dev->pm.ds_enable_user = true;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index 0dec25b320f8..0f76d9197230 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -416,8 +416,8 @@ static int mt7927_dma_init(struct mt792x_dev *dev)
 	napi_enable(&dev->mt76.tx_napi);
 
 	/* MT7927-specific GLO_CFG bits before DMA enable */
-	mt76_set(dev, MT_WFDMA0_GLO_CFG, BIT(26));   /* ADDR_EXT_EN */
-	mt76_clear(dev, MT_WFDMA0_GLO_CFG, BIT(20)); /* CSR_LBK_RX_Q_SEL_EN */
+	mt76_set(dev, MT_WFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_ADDR_EXT_EN);
+	mt76_clear(dev, MT_WFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_CSR_LBK_RX_Q_SEL_EN);
 	mt76_set(dev, MT_WFDMA0_GLO_CFG_EXT1, BIT(28));
 	mt76_set(dev, MT_WFDMA0_GLO_CFG,
 		 MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL);
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
index 3177c6cc6eb5..32364f19007d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
@@ -166,6 +166,13 @@ int mt792x_dma_enable(struct mt792x_dev *dev)
 	mt76_set(dev, MT_WFDMA0_GLO_CFG,
 		 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
 
+	if (is_mt7927(&dev->mt76)) {
+		mt76_set(dev, MT_WFDMA0_GLO_CFG,
+			 MT_WFDMA0_GLO_CFG_ADDR_EXT_EN);
+		mt76_clear(dev, MT_WFDMA0_GLO_CFG,
+			   MT_WFDMA0_GLO_CFG_CSR_LBK_RX_Q_SEL_EN);
+	}
+
 	if (is_mt7925(&dev->mt76)) {
 		mt76_rmw(dev, MT_UWFDMA0_GLO_CFG_EXT1, BIT(28), BIT(28));
 		mt76_set(dev, MT_WFDMA0_INT_RX_PRI, 0x0F00);
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
index 5497cfaab8d7..b364d0038653 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
@@ -299,7 +299,9 @@
 #define MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN	BIT(12)
 #define MT_WFDMA0_GLO_CFG_RX_WB_DDONE	BIT(13)
 #define MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN BIT(15)
+#define MT_WFDMA0_GLO_CFG_CSR_LBK_RX_Q_SEL_EN	BIT(20)
 #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2	BIT(21)
+#define MT_WFDMA0_GLO_CFG_ADDR_EXT_EN		BIT(26)
 #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO	BIT(27)
 #define MT_WFDMA0_GLO_CFG_OMIT_TX_INFO	BIT(28)
 #define MT_WFDMA0_GLO_CFG_CLK_GAT_DIS	BIT(30)

-- 
2.53.0


^ permalink raw reply related

* [PATCH 11/18] wifi: mt76: mt7925: fix uninitialized is_mt7927_hw in probe
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

is_mt7927_hw was declared at the top of mt7925_pci_probe() but only
assigned after its first use at the irq_map selection. The uninitialized
value (typically zero on x86_64) caused the mt7925 IRQ map to be selected
instead of mt7927_irq_map. With the wrong map the driver polls RX rings
0/2 instead of 4/6/7, so MCU responses are never received and every
command times out with "Failed to get patch semaphore".

Fix by initializing is_mt7927_hw at declaration from pdev->device.

Also remove a stale MT_WFDMA0_GLO_CFG_EXT1 define that pointed to the
wrong register address (MT_WFDMA0 base 0xd4000 instead of MT_UWFDMA0
base 0x24000). The correct BIT(28) write is already handled by
mt792x_dma_enable() via MT_UWFDMA0_GLO_CFG_EXT1.

Reported-by: 张旭涵 <Loong.0x00@gmail.com>
Closes: https://github.com/jetm/mediatek-mt7927-dkms/issues/15
Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index 0f76d9197230..6275e78777b0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -418,7 +418,6 @@ static int mt7927_dma_init(struct mt792x_dev *dev)
 	/* MT7927-specific GLO_CFG bits before DMA enable */
 	mt76_set(dev, MT_WFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_ADDR_EXT_EN);
 	mt76_clear(dev, MT_WFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_CSR_LBK_RX_Q_SEL_EN);
-	mt76_set(dev, MT_WFDMA0_GLO_CFG_EXT1, BIT(28));
 	mt76_set(dev, MT_WFDMA0_GLO_CFG,
 		 MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL);
 
@@ -489,7 +488,7 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	struct mt76_bus_ops *bus_ops;
 	struct mt792x_dev *dev;
 	struct mt76_dev *mdev;
-	bool is_mt7927_hw;
+	bool is_mt7927_hw = (pdev->device == 0x6639 || pdev->device == 0x7927);
 	u8 features;
 	int ret;
 	u16 cmd;
@@ -574,8 +573,6 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	if (!mt7925_disable_aspm && mt76_pci_aspm_supported(pdev))
 		dev->aspm_supported = true;
 
-	is_mt7927_hw = (pdev->device == 0x6639 || pdev->device == 0x7927);
-
 	ret = __mt792x_mcu_fw_pmctrl(dev);
 	if (ret)
 		goto err_free_dev;

-- 
2.53.0


^ permalink raw reply related

* [PATCH 12/18] wifi: mt76: mt7925: advertise EHT 320MHz capabilities for 6GHz band
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

mt7925_init_eht_caps() only populates EHT MCS/NSS maps for BW <= 80
and BW = 160, but never sets BW = 320. This means iw phy shows no
320MHz MCS map entries even though the hardware supports 320MHz
operation in the 6GHz band.

Add the missing 320MHz capability bits for 6GHz, following the same
pattern as mt7996:
  - PHY_CAP0: IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ
  - PHY_CAP1: beamformee SS for 320MHz
  - PHY_CAP2: sounding dimensions for 320MHz
  - PHY_CAP6: MCS15 support for 320MHz width
  - PHY_CAP7: non-OFDMA UL MU-MIMO and MU beamformer for 320MHz
  - MCS/NSS: populate bw._320 maps for 6GHz band

Guard all 320MHz capability advertisements behind is_mt7927() since
320MHz support has only been validated on MT7927 hardware. The mt7925
standalone chip may not support 320MHz operation.

Assisted-by: Claude Code <noreply@anthropic.com> (claude-opus-4-6)
Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/main.c | 28 +++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index 2d358a96640c..4e1265886f20 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -183,6 +183,10 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
 		IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER |
 		IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;
 
+	if (band == NL80211_BAND_6GHZ && is_mt7927(&phy->dev->mt76))
+		eht_cap_elem->phy_cap_info[0] |=
+			IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
+
 	eht_cap_elem->phy_cap_info[0] |=
 		u8_encode_bits(u8_get_bits(sts - 1, BIT(0)),
 			       IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK);
@@ -193,10 +197,20 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
 		u8_encode_bits(sts - 1,
 			       IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK);
 
+	if (band == NL80211_BAND_6GHZ && is_mt7927(&phy->dev->mt76))
+		eht_cap_elem->phy_cap_info[1] |=
+			u8_encode_bits(sts - 1,
+				       IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK);
+
 	eht_cap_elem->phy_cap_info[2] =
 		u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_80MHZ_MASK) |
 		u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_160MHZ_MASK);
 
+	if (band == NL80211_BAND_6GHZ && is_mt7927(&phy->dev->mt76))
+		eht_cap_elem->phy_cap_info[2] |=
+			u8_encode_bits(sts - 1,
+				       IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK);
+
 	eht_cap_elem->phy_cap_info[3] =
 		IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK |
 		IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK |
@@ -217,7 +231,8 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
 		u8_encode_bits(u8_get_bits(0x11, GENMASK(1, 0)),
 			       IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK);
 
-	val = width == NL80211_CHAN_WIDTH_160 ? 0x7 :
+	val = width == NL80211_CHAN_WIDTH_320 ? 0xf :
+	      width == NL80211_CHAN_WIDTH_160 ? 0x7 :
 	      width == NL80211_CHAN_WIDTH_80 ? 0x3 : 0x1;
 	eht_cap_elem->phy_cap_info[6] =
 		u8_encode_bits(u8_get_bits(0x11, GENMASK(4, 2)),
@@ -230,6 +245,11 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
 		IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ |
 		IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ;
 
+	if (band == NL80211_BAND_6GHZ && is_mt7927(&phy->dev->mt76))
+		eht_cap_elem->phy_cap_info[7] |=
+			IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ |
+			IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ;
+
 	val = u8_encode_bits(nss, IEEE80211_EHT_MCS_NSS_RX) |
 	      u8_encode_bits(nss, IEEE80211_EHT_MCS_NSS_TX);
 
@@ -239,6 +259,12 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
 	eht_nss->bw._160.rx_tx_mcs9_max_nss = val;
 	eht_nss->bw._160.rx_tx_mcs11_max_nss = val;
 	eht_nss->bw._160.rx_tx_mcs13_max_nss = val;
+
+	if (band == NL80211_BAND_6GHZ && is_mt7927(&phy->dev->mt76)) {
+		eht_nss->bw._320.rx_tx_mcs9_max_nss = val;
+		eht_nss->bw._320.rx_tx_mcs11_max_nss = val;
+		eht_nss->bw._320.rx_tx_mcs13_max_nss = val;
+	}
 }
 
 int mt7925_init_mlo_caps(struct mt792x_phy *phy)

-- 
2.53.0


^ permalink raw reply related

* [PATCH 13/18] wifi: mt76: mt7925: restore FW_DWLD_BYPASS_DMASHDL in MT7927 PM wake path
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

mt7927_dma_init() sets FW_DWLD_BYPASS_DMASHDL (BIT(9) of GLO_CFG)
during initial probe, but mt792x_dma_enable() - called on every PM
wake cycle - did not restore it. On MT7927, every CLR_OWN causes the
ROM to reinitialize WFDMA which resets GLO_CFG. The PM wake path
already restores ADDR_EXT_EN and clears CSR_LBK_RX_Q_SEL_EN but was
missing FW_DWLD_BYPASS_DMASHDL.

Add FW_DWLD_BYPASS_DMASHDL to the existing is_mt7927() block in
mt792x_dma_enable() so all three MT7927-specific GLO_CFG bits are
consistently restored after PM wake.

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt792x_dma.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
index 32364f19007d..95082d64fb69 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
@@ -168,7 +168,8 @@ int mt792x_dma_enable(struct mt792x_dev *dev)
 
 	if (is_mt7927(&dev->mt76)) {
 		mt76_set(dev, MT_WFDMA0_GLO_CFG,
-			 MT_WFDMA0_GLO_CFG_ADDR_EXT_EN);
+			 MT_WFDMA0_GLO_CFG_ADDR_EXT_EN |
+			 MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL);
 		mt76_clear(dev, MT_WFDMA0_GLO_CFG,
 			   MT_WFDMA0_GLO_CFG_CSR_LBK_RX_Q_SEL_EN);
 	}

-- 
2.53.0


^ permalink raw reply related

* [PATCH 14/18] wifi: mt76: mt7925: disable ASPM for MT7927 to fix throughput collapse
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

MT7927 (MT7927) exhibits severe throughput degradation when PCIe ASPM
L1 is active.  Upload throughput drops from 1+ Gbps to ~200 Mbps, and
intermittent download drops to ~69 Mbps have been observed.

The root cause is that MT7927's CONNINFRA power domain and WFDMA
register access are unreliable when the PCIe link transitions in and
out of L1 sleep state.  Unlike MT7925, MT7927 depends on CONNINFRA
being continuously accessible for CBTOP address remap, and its ROM
reinitializes WFDMA on every CLR_OWN which can race with L1
transitions.

Disable ASPM unconditionally for MT7927 at probe time using the
existing mt76_pci_disable_aspm() helper, which handles both the device
and parent bridge.  This disables L0s in addition to L1; L0s power
savings are negligible for a PCIe WLAN card and this avoids needing a
separate L1-only code path with CONFIG_PCIEASPM fallback handling.

After the disable, mt76_pci_aspm_supported() returns false so the
2-3 ms delay in __mt792xe_mcu_drv_pmctrl() is correctly skipped.
The pci_disable_link_state() call persists across suspend/resume.

Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index 6275e78777b0..e6830404c8fc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -516,7 +516,14 @@ static int mt7925_pci_probe(struct pci_dev *pdev,
 	if (ret)
 		goto err_free_pci_vec;
 
-	if (mt7925_disable_aspm)
+	/* MT7927 CONNINFRA power domain and WFDMA register access are
+	 * unreliable with PCIe L1 active, causing throughput to drop
+	 * from 1+ Gbps to ~200 Mbps.  Disable ASPM unconditionally
+	 * rather than only L1, since L0s savings are negligible for
+	 * a PCIe WLAN card and mt76_pci_disable_aspm() already
+	 * handles both device and parent bridge in one call.
+	 */
+	if (mt7925_disable_aspm || is_mt7927_hw)
 		mt76_pci_disable_aspm(pdev);
 
 	ops = mt792x_get_mac80211_ops(&pdev->dev, &mt7925_ops,

-- 
2.53.0


^ permalink raw reply related

* [PATCH 15/18] wifi: mt76: mt7925: handle 320MHz bandwidth in RXV and TXS
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

The RX vector (RXV) and TX status (TXS) parsing in mac.c lack handling
for 320MHz channel width. When the hardware reports 320MHz in the
bandwidth field, mt7925_mac_fill_rx_rate() returns -EINVAL and
mt7925_mac_add_txs_skb() records no bandwidth stats.

Add IEEE80211_STA_RX_BW_320 cases to both functions. The RXV parser
also handles BW_320+1 since the hardware can report 320MHz in two
adjacent encoding positions.

Also fix whitespace alignment in mt792x_regs.h defines.

Assisted-by: Claude Code <noreply@anthropic.com> (claude-opus-4-6)
Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/mac.c  | 9 +++++++++
 drivers/net/wireless/mediatek/mt76/mt792x_regs.h | 6 +++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
index caaf71c31480..ad03fc554b69 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
@@ -339,6 +339,11 @@ mt7925_mac_fill_rx_rate(struct mt792x_dev *dev,
 	case IEEE80211_STA_RX_BW_160:
 		status->bw = RATE_INFO_BW_160;
 		break;
+	/* RXV can report 320 in two positions */
+	case IEEE80211_STA_RX_BW_320:
+	case IEEE80211_STA_RX_BW_320 + 1:
+		status->bw = RATE_INFO_BW_320;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -992,6 +997,10 @@ mt7925_mac_add_txs_skb(struct mt792x_dev *dev, struct mt76_wcid *wcid,
 	stats->tx_mode[mode]++;
 
 	switch (FIELD_GET(MT_TXS0_BW, txs)) {
+	case IEEE80211_STA_RX_BW_320:
+		rate.bw = RATE_INFO_BW_320;
+		stats->tx_bw[4]++;
+		break;
 	case IEEE80211_STA_RX_BW_160:
 		rate.bw = RATE_INFO_BW_160;
 		stats->tx_bw[3]++;
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
index b364d0038653..a2ce6872559e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
@@ -301,9 +301,9 @@
 #define MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN BIT(15)
 #define MT_WFDMA0_GLO_CFG_CSR_LBK_RX_Q_SEL_EN	BIT(20)
 #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2	BIT(21)
-#define MT_WFDMA0_GLO_CFG_ADDR_EXT_EN		BIT(26)
 #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO	BIT(27)
 #define MT_WFDMA0_GLO_CFG_OMIT_TX_INFO	BIT(28)
+#define MT_WFDMA0_GLO_CFG_ADDR_EXT_EN		BIT(26)
 #define MT_WFDMA0_GLO_CFG_CLK_GAT_DIS	BIT(30)
 
 #define HOST_RX_DONE_INT_ENA0		BIT(0)
@@ -509,8 +509,8 @@
 #define MT_MCIF_REMAP_WF_1_BA		0xd1034
 
 /* CBInfra CBTOP remap values */
-#define MT_CBINFRA_REMAP_WF_VAL	0x74037001
-#define MT_CBINFRA_REMAP_BT_VAL	0x70007000
+#define MT_CBINFRA_REMAP_WF_VAL		0x74037001
+#define MT_CBINFRA_REMAP_BT_VAL		0x70007000
 
 #define MT_MCIF_REMAP_WF_1_BA_VAL	0x18051803
 

-- 
2.53.0


^ permalink raw reply related

* [PATCH 16/18] wifi: mt76: mt7925: fix stale pointer comparisons in change_vif_links
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

In the error path of mt7925_change_vif_links(), the free: label iterates
over link_ids to clean up, but compares against `mconf` and `mlink`
which hold stale values from the last loop iteration rather than the
current link_id being freed.

Use array-indexed access (mconfs[link_id] / mlinks[link_id]) to compare
against the correct per-link pointers.

Fixes: 69acd6d910b0 ("wifi: mt76: mt7925: add MLO support")
Assisted-by: Claude Code <noreply@anthropic.com> (claude-opus-4-6)
Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index 4e1265886f20..f82c56c46324 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -2073,9 +2073,9 @@ mt7925_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		rcu_assign_pointer(mvif->link_conf[link_id], NULL);
 		rcu_assign_pointer(mvif->sta.link[link_id], NULL);
 
-		if (mconf != &mvif->bss_conf)
+		if (mconfs[link_id] != &mvif->bss_conf)
 			devm_kfree(dev->mt76.dev, mconfs[link_id]);
-		if (mlink != &mvif->sta.deflink)
+		if (mlinks[link_id] != &mvif->sta.deflink)
 			devm_kfree(dev->mt76.dev, mlinks[link_id]);
 	}
 

-- 
2.53.0


^ permalink raw reply related

* [PATCH 17/18] wifi: mt76: mt7925: fix MT7927 band_idx for stable 5GHz/6GHz operation
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

The MT7927 (Filogic 380) firmware requires explicit band_idx assignment
(0 for 2.4GHz, 1 for 5GHz/6GHz) instead of 0xff (auto-select) used by
MT7925. Without this, the firmware selects the wrong radio for 5GHz and
6GHz connections, causing WPA 4-way handshake timeout and data plane
failures on those bands.

Add mt7925_mt7927_hw_band_from_nl() helper to map nl80211_band to
hardware band index, and use it throughout the driver:

  - mac_link_bss_add: set band_idx from link channel at BSS creation
  - assign_vif_chanctx: update band_idx when channel context changes,
    resend DEV_INFO to firmware if band changed
  - bss_basic_tlv: set band_idx in BSS info sent to firmware
  - set_roc / set_mlo_roc / abort_roc: send concrete dbdcband instead
    of 0xff auto-select
  - roc_iter / roc_handle_grant: clamp invalid grant band_idx values
    using rfband as fallback, process grants for all MT7927 request
    types (not just JOIN)

All changes guarded by is_mt7927() - no impact on MT7925 behavior.

Originally discovered and fixed by marcin-fm; Loong0x00 contributed
additional improvements based on marcin-fm's patch.

Co-developed-by: Marcin FM <marcin@lgic.pl>
Signed-off-by: Marcin FM <marcin@lgic.pl>
Co-developed-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: 张旭涵 <Loong.0x00@gmail.com>
Assisted-by: Claude Code <noreply@anthropic.com> (claude-opus-4-6)
Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/main.c   | 40 +++++++++++++++-
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c    | 54 ++++++++++++++++++----
 drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h |  5 ++
 3 files changed, 87 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index f82c56c46324..fcb9f26c8b87 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -400,7 +400,24 @@ static int mt7925_mac_link_bss_add(struct mt792x_dev *dev,
 
 	mconf->mt76.omac_idx = ieee80211_vif_is_mld(vif) ?
 			       0 : mconf->mt76.idx;
-	mconf->mt76.band_idx = 0xff;
+
+	if (is_mt7927(&dev->mt76)) {
+		struct ieee80211_channel *chan = NULL;
+
+		if (link_conf->chanreq.oper.chan)
+			chan = link_conf->chanreq.oper.chan;
+		else if (mvif->phy->mt76->chandef.chan)
+			chan = mvif->phy->mt76->chandef.chan;
+
+		if (chan)
+			mconf->mt76.band_idx =
+				mt7925_mt7927_hw_band_from_nl(chan->band);
+		else
+			mconf->mt76.band_idx = 0xff;
+	} else {
+		mconf->mt76.band_idx = 0xff;
+	}
+
 	mconf->mt76.wmm_idx = ieee80211_vif_is_mld(vif) ?
 			      0 : mconf->mt76.idx % MT76_CONNAC_MAX_WMM_SETS;
 	mconf->mt76.link_idx = hweight16(mvif->valid_links);
@@ -417,7 +434,8 @@ static int mt7925_mac_link_bss_add(struct mt792x_dev *dev,
 
 	mlink->wcid.idx = idx;
 	mlink->wcid.tx_info |= MT_WCID_TX_INFO_SET;
-	mt76_wcid_init(&mlink->wcid, 0);
+	mt76_wcid_init(&mlink->wcid,
+		       mconf->mt76.band_idx == 0xff ? 0 : mconf->mt76.band_idx);
 
 	mt7925_mac_wtbl_update(dev, idx,
 			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
@@ -2119,9 +2137,12 @@ static int mt7925_assign_vif_chanctx(struct ieee80211_hw *hw,
 {
 	struct mt792x_chanctx *mctx = (struct mt792x_chanctx *)ctx->drv_priv;
 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
+	struct mt792x_link_sta *mlink;
 	struct mt792x_dev *dev = mt792x_hw_dev(hw);
 	struct ieee80211_bss_conf *pri_link_conf;
 	struct mt792x_bss_conf *mconf;
+	u8 band_idx;
+	u8 old_band;
 
 	mutex_lock(&dev->mt76.mutex);
 
@@ -2137,6 +2158,21 @@ static int mt7925_assign_vif_chanctx(struct ieee80211_hw *hw,
 		mconf = &mvif->bss_conf;
 	}
 
+	old_band = mconf->mt76.band_idx;
+	if (is_mt7927(&dev->mt76) && ctx->def.chan) {
+		band_idx = mt7925_mt7927_hw_band_from_nl(ctx->def.chan->band);
+		mconf->mt76.band_idx = band_idx;
+		mlink = mt792x_sta_to_link(&mvif->sta, mconf->link_id);
+		if (mlink)
+			mlink->wcid.phy_idx = band_idx;
+
+		if (old_band != band_idx && vif->type == NL80211_IFTYPE_STATION &&
+		    mlink)
+			mt76_connac_mcu_uni_add_dev(&dev->mphy, link_conf,
+						    &mconf->mt76, &mlink->wcid,
+						    true);
+	}
+
 	mconf->mt76.ctx = ctx;
 	mctx->bss_conf = mconf;
 	mutex_unlock(&dev->mt76.mutex);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index 8b5ffb240d52..3458aa8c79cb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -301,16 +301,36 @@ mt7925_mcu_connection_loss_event(struct mt792x_dev *dev, struct sk_buff *skb)
 static void
 mt7925_mcu_roc_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 {
-	struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
+	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
 	struct mt7925_roc_grant_tlv *grant = priv;
+	u8 band_idx = grant->dbdcband;
 
 	if (ieee80211_vif_is_mld(vif) && vif->type == NL80211_IFTYPE_STATION)
 		return;
 
-	if (mvif->idx != grant->bss_idx)
+	if (mvif->bss_conf.mt76.idx != grant->bss_idx)
 		return;
 
-	mvif->band_idx = grant->dbdcband;
+	/* MT7927 firmware requires band_idx 0 (2.4G) or 1 (5/6G).
+	 * Clamp invalid grant values using rfband as fallback.
+	 */
+	if (is_mt7927(&mvif->phy->dev->mt76) && band_idx > 1) {
+		switch (grant->rfband) {
+		case 1: /* 2.4 GHz */
+			band_idx = 0;
+			break;
+		case 2: /* 5 GHz */
+		case 3: /* 6 GHz */
+			band_idx = 1;
+			break;
+		default:
+			band_idx = mvif->bss_conf.mt76.band_idx <= 1 ?
+				   mvif->bss_conf.mt76.band_idx : 0;
+			break;
+		}
+	}
+
+	mvif->bss_conf.mt76.band_idx = band_idx;
 }
 
 static void mt7925_mcu_roc_handle_grant(struct mt792x_dev *dev,
@@ -327,10 +347,11 @@ static void mt7925_mcu_roc_handle_grant(struct mt792x_dev *dev,
 
 	if (grant->reqtype == MT7925_ROC_REQ_ROC)
 		ieee80211_ready_on_channel(hw);
-	else if (grant->reqtype == MT7925_ROC_REQ_JOIN)
+	else if (is_mt7927(&dev->mt76) || grant->reqtype == MT7925_ROC_REQ_JOIN)
 		ieee80211_iterate_active_interfaces_atomic(hw,
 						IEEE80211_IFACE_ITER_RESUME_ALL,
 						mt7925_mcu_roc_iter, grant);
+
 	dev->phy.roc_grant = true;
 	wake_up(&dev->phy.roc_wait);
 	duration = le32_to_cpu(grant->max_interval);
@@ -1378,10 +1399,15 @@ int mt7925_mcu_set_mlo_roc(struct mt792x_bss_conf *mconf, u16 sel_links,
 		req.roc[i].center_chan2 = 0;
 		req.roc[i].center_chan2_from_ap = 0;
 
-		/* STR : 0xfe indicates BAND_ALL with enabling DBDC
-		 * EMLSR : 0xff indicates (BAND_AUTO) without DBDC
-		 */
-		req.roc[i].dbdcband = type == MT7925_ROC_REQ_JOIN ? 0xfe : 0xff;
+		if (is_mt7927(&mvif->phy->dev->mt76))
+			req.roc[i].dbdcband =
+				mt7925_mt7927_hw_band_from_nl(chan->band);
+		else
+			/* STR : 0xfe indicates BAND_ALL with enabling DBDC
+			 * EMLSR : 0xff indicates (BAND_AUTO) without DBDC
+			 */
+			req.roc[i].dbdcband = type == MT7925_ROC_REQ_JOIN ?
+					      0xfe : 0xff;
 
 		if (chan->hw_value < center_ch)
 			req.roc[i].sco = 1; /* SCA */
@@ -1419,7 +1445,9 @@ int mt7925_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_bss_conf *mconf,
 			.bw_from_ap = CMD_CBW_20MHZ,
 			.center_chan = center_ch,
 			.center_chan_from_ap = center_ch,
-			.dbdcband = 0xff, /* auto */
+			.dbdcband = is_mt7927(&dev->mt76) ?
+				    mt7925_mt7927_hw_band_from_nl(chan->band) :
+				    0xff, /* auto */
 		},
 	};
 
@@ -1466,7 +1494,10 @@ int mt7925_mcu_abort_roc(struct mt792x_phy *phy, struct mt792x_bss_conf *mconf,
 			.len = cpu_to_le16(sizeof(struct roc_abort_tlv)),
 			.tokenid = token_id,
 			.bss_idx = mconf->mt76.idx,
-			.dbdcband = 0xff, /* auto*/
+			.dbdcband = is_mt7927(&dev->mt76) &&
+				    mconf->mt76.band_idx <= 1 ?
+				    mconf->mt76.band_idx :
+				    0xff, /* auto */
 		},
 	};
 
@@ -2495,6 +2526,9 @@ mt7925_mcu_bss_basic_tlv(struct sk_buff *skb,
 	basic_req->phymode_ext = mt7925_get_phy_mode_ext(phy, vif, band,
 							 link_sta);
 
+	if (is_mt7927(phy->dev))
+		mconf->mt76.band_idx = mt7925_mt7927_hw_band_from_nl(band);
+
 	if (band == NL80211_BAND_2GHZ)
 		basic_req->nonht_basic_phy = cpu_to_le16(PHY_TYPE_ERP_INDEX);
 	else
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
index ba3d2c4de4ce..d3c89ea0afab 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
@@ -63,6 +63,11 @@ enum mt7925_roc_req {
 	MT7925_ROC_REQ_NUM
 };
 
+static inline u8 mt7925_mt7927_hw_band_from_nl(enum nl80211_band band)
+{
+	return band == NL80211_BAND_2GHZ ? 0 : 1;
+}
+
 enum {
 	UNI_EVENT_ROC_GRANT = 0,
 	UNI_EVENT_ROC_GRANT_SUB_LINK = 4,

-- 
2.53.0


^ permalink raw reply related

* [PATCH 18/18] wifi: mt76: mt7925: add 320MHz bandwidth to bss_rlm_tlv
From: Javier Tia @ 2026-03-07  0:33 UTC (permalink / raw)
  To: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵, Javier Tia
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

bss_rlm_tlv() in mt7925_mcu_bss_rlm_tlv() has no case for
NL80211_CHAN_WIDTH_320. When associated to a 320MHz BSS, the switch
falls through to default and sends bw=0 (CMD_CBW_20MHZ) to firmware
via BSS_RLM TLV. Firmware then configures the RX radio for 20MHz
and cannot decode the AP's 320MHz frames, resulting in complete data
path failure at 320MHz.

Add the missing NL80211_CHAN_WIDTH_320 case with CMD_CBW_320MHZ and
center_chan2.

Tested on ASUS RT-BE92U: 320MHz throughput goes from 0 Mbps to
841 Mbps (iperf3 -t30 -P8), PHY 4803 Mbps EHT-MCS11.

Reported-by: 张旭涵 <Loong.0x00@gmail.com>
Closes: https://github.com/jetm/mediatek-mt7927-dkms/issues/15
Assisted-by: Claude Code <noreply@anthropic.com> (claude-opus-4-6)
Tested-by: 张旭涵 <Loong.0x00@gmail.com>
Tested-by: Marcin FM <marcin@lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
Tested-by: George Salukvadze <giosal90@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Thibaut François <tibo@humeurlibre.fr>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index 3458aa8c79cb..025e6d14f7ce 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -2363,6 +2363,10 @@ void mt7925_mcu_bss_rlm_tlv(struct sk_buff *skb, struct mt76_phy *phy,
 	case NL80211_CHAN_WIDTH_160:
 		req->bw = CMD_CBW_160MHZ;
 		break;
+	case NL80211_CHAN_WIDTH_320:
+		req->bw = CMD_CBW_320MHZ;
+		req->center_chan2 = ieee80211_frequency_to_channel(freq2);
+		break;
 	case NL80211_CHAN_WIDTH_5:
 		req->bw = CMD_CBW_5MHZ;
 		break;

-- 
2.53.0


^ permalink raw reply related

* Re: [BUG] wifi: mt76: mt7925u: probe with driver mt7925u failed with error -110
From: Sean Wang @ 2026-03-07  0:46 UTC (permalink / raw)
  To: Nick
  Cc: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Deren Wu, Leon Yen
In-Reply-To: <CAFktD2eG+nebKcNbw2imufSOz6MCR-SUXjcUQmDqJabNfwx4sg@mail.gmail.com>

Hi Nick,

Thanks for the detailed report  this is very helpful. I don't  have an
MT7925 USB device to detail look into the issue, but based on the
trace I wrote a small change to try a different MT7925 reset sequence.
please help test.

--- a/drivers/net/wireless/mediatek/mt76/mt792x_usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_usb.c
@@ -234,6 +234,36 @@ int mt792xu_dma_init(struct mt792x_dev *dev, bool resume)
 }
 EXPORT_SYMBOL_GPL(mt792xu_dma_init);

+static int mt7925u_wfsys_reset(struct mt792x_dev *dev)
+{
+    u32 val;
+    int i;
+
+#define MT7925_CBTOP_RGU_WF_SUBSYS_RST        0x70028600
+#define MT7925_WFSYS_SW_INIT_DONE_ADDR        0x184c1604
+#define MT7925_WFSYS_SW_INIT_DONE        0x00001d1e
+
+    val = mt792xu_uhw_rr(&dev->mt76, MT7925_CBTOP_RGU_WF_SUBSYS_RST);
+    val |= MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH;
+    mt792xu_uhw_wr(&dev->mt76, MT7925_CBTOP_RGU_WF_SUBSYS_RST, val);
+
+    msleep(20);
+
+    val = mt792xu_uhw_rr(&dev->mt76, MT7925_CBTOP_RGU_WF_SUBSYS_RST);
+    val &= ~MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH;
+    mt792xu_uhw_wr(&dev->mt76, MT7925_CBTOP_RGU_WF_SUBSYS_RST, val);
+
+    for (i = 0; i < MT792x_WFSYS_INIT_RETRY_COUNT; i++) {
+        val = mt792xu_uhw_rr(&dev->mt76, MT7925_WFSYS_SW_INIT_DONE_ADDR);
+        if (val == MT7925_WFSYS_SW_INIT_DONE)
+            return 0;
+
+        msleep(100);
+    }
+
+    return -ETIMEDOUT;
+}
+
 int mt792xu_wfsys_reset(struct mt792x_dev *dev)
 {
     u32 val;
@@ -241,6 +271,9 @@ int mt792xu_wfsys_reset(struct mt792x_dev *dev)

     mt792xu_epctl_rst_opt(dev, false);

+    if (is_mt7925(&dev->mt76))
+        return mt7925u_wfsys_reset(dev);
+
     val = mt792xu_uhw_rr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST);


On Fri, Mar 6, 2026 at 1:24 PM Nick <morrownr@gmail.com> wrote:
>
> > > Reference: https://github.com/morrownr/USB-WiFi/issues/688#issuecomment-3999038526
> > >
> > > The above thread is rather lengthy as we have been working on this
> > > issue since Dec. 25.
> > >
> > > Testing with a Netgear A9000 USB WiFi adapter (mt7925u driver). Kernel
> > > 7.0 rc2 and a x86_64 system. Additional testing with older kernels was
> > > also performed with the same results.
> > >
> > > Problem description:
> > >
> > > Cold boot shows the adapter coming up and operating normally.
> > >
> > > Removing the adapter from the USB port and replacing it shows the
> > > adapter coming up and operating normally.
> > >
> > > A warm reboot does not provide a WiFi interface and shows the
> > > following in the system log:
> > >
> > > mt7925u 2-3.2:1.0: probe with driver mt7925u failed with error -110
> > >
> > > Using the commands rmmod and modeprobe do not provide a WiFi interface.
> > >
> > > Thoughts: The problem likely is not the module teardown. The problem
> > > seems to be that the firmware (or the mt7925u driver) leaves the
> > > adapter in a strange state such that a power cycle of the adapter
> > > hardware is needed before the mt7925u driver can properly initialize
> > > it a second time.
> > >
> >
> > Hi Nick,
> >
> > Could you enable debug logs and check whether the driver can still
> > read the correct chip ID after a warm reboot, and at which step the
> > initialization fails before the -110 error? Thanks for continuing to
> > test and gather this useful information.
> >
> >          Sean
>
> Hi Sean,
>
> Github user @exct has performed the testing requested and provides the
> following report:
>
> mt7925u Probe Failure Debug Report
> Adapter: Netgear A9000 (USB ID 0846:9072, MediaTek MT7925)
> Kernel: 6.19.6-2-cachyos
>
> Summary
> The driver can read the correct chip ID after a warm reload. The
> failure occurs before firmware is loaded, inside
> mt792xu_wfsys_reset(), which times out waiting for the WiFi subsystem
> to reinitialize. -ETIMEDOUT (-110) is returned and the probe aborts.
>
> Findings
>
> Question: Chip ID readable after warm reload?
> Answer: Yes — MT_HW_CHIPID = 0x7925, MT_HW_REV = 0x8a00
>
> Question: Which step fails?
> Answer: mt792xu_wfsys_reset() — WFSYS_INIT_DONE never asserted
>
> Question: Does it reach mt792xu_mcu_power_on()?
> Answer: No
>
> Question: Does it reach mt7925_run_firmware()?
> Answer: No
>
> Probe Sequence Trace
>
> mt7925u_probe()
>   ├─ mt76_alloc_device()             OK
>   ├─ __mt76u_init()                  OK
>   ├─ read MT_HW_CHIPID (0x70010200)  → 0x00007925  ✓
>   ├─ read MT_HW_REV    (0x70010204)  → 0x00008a00  ✓
>   ├─ read MT_CONN_ON_MISC (0x7c0600f0) → 0x00000003  ← FW_N9_RDY is SET
>   ├─ enters mt792xu_wfsys_reset()    ← triggered because FW_N9_RDY = 1
>   │    ├─ write MT_CBTOP_RGU_WF_SUBSYS_RST  (assert reset)
>   │    ├─ write MT_CBTOP_RGU_WF_SUBSYS_RST  (deassert reset)
>   │    ├─ poll MT_UDMA_CONN_INFRA_STATUS (0x74000a20) → 0x00000000
>   │    ├─ poll MT_UDMA_CONN_INFRA_STATUS (0x74000a20) → 0x00000000
>   │    └─ ... timeout after ~212 ms → return -ETIMEDOUT
>   └─ goto error:  (mt76u_queues_deinit + mt76_free_device)
>
> Root Cause
>
> After rmmod, the firmware leaves FW_N9_RDY asserted in
> MT_CONN_ON_MISC. On re-probe, the driver correctly detects this and
> calls mt792xu_wfsys_reset() to recover. However, the WiFi subsystem
> never signals completion — WFSYS_INIT_DONE in
> MT_UDMA_CONN_INFRA_STATUS (reg 0x74000a20) stays 0x00000000 throughout
> the retry loop. The subsystem is stuck in a state that the software
> reset path cannot recover from. Only a full USB power cycle clears it.
>
> Hope this helps,
>
> Nick

^ permalink raw reply

* [wireless-next:for-next] BUILD SUCCESS 97492c019da4b62df83255e968b23b81c0315530
From: kernel test robot @ 2026-03-07  5:04 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git for-next
branch HEAD: 97492c019da4b62df83255e968b23b81c0315530  wifi: mwifiex: drop redundant device reference

elapsed time: 1108m

configs tested: 196
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig    gcc-15.2.0
alpha                            allyesconfig    gcc-15.2.0
alpha                               defconfig    gcc-15.2.0
arc                              allmodconfig    clang-16
arc                              allmodconfig    gcc-15.2.0
arc                               allnoconfig    gcc-15.2.0
arc                              allyesconfig    clang-23
arc                              allyesconfig    gcc-15.2.0
arc                                 defconfig    gcc-15.2.0
arc                   randconfig-001-20260307    gcc-15.2.0
arc                   randconfig-002-20260307    gcc-15.2.0
arm                               allnoconfig    clang-23
arm                               allnoconfig    gcc-15.2.0
arm                              allyesconfig    clang-16
arm                              allyesconfig    gcc-15.2.0
arm                        clps711x_defconfig    clang-23
arm                                 defconfig    gcc-15.2.0
arm                   randconfig-001-20260307    gcc-15.2.0
arm                   randconfig-002-20260307    gcc-15.2.0
arm                   randconfig-003-20260307    gcc-15.2.0
arm                   randconfig-004-20260307    gcc-15.2.0
arm                           u8500_defconfig    gcc-15.2.0
arm64                            allmodconfig    clang-19
arm64                            allmodconfig    clang-23
arm64                             allnoconfig    gcc-15.2.0
arm64                               defconfig    gcc-15.2.0
arm64                 randconfig-001-20260307    gcc-8.5.0
arm64                 randconfig-002-20260307    gcc-8.5.0
arm64                 randconfig-003-20260307    gcc-8.5.0
arm64                 randconfig-004-20260307    gcc-8.5.0
csky                             allmodconfig    gcc-15.2.0
csky                              allnoconfig    gcc-15.2.0
csky                                defconfig    gcc-15.2.0
csky                  randconfig-001-20260307    gcc-8.5.0
csky                  randconfig-002-20260307    gcc-8.5.0
hexagon                          allmodconfig    gcc-15.2.0
hexagon                           allnoconfig    clang-23
hexagon                           allnoconfig    gcc-15.2.0
hexagon                             defconfig    gcc-15.2.0
hexagon               randconfig-001-20260307    gcc-15.2.0
hexagon               randconfig-002-20260307    gcc-15.2.0
i386                             allmodconfig    clang-20
i386                              allnoconfig    gcc-14
i386                              allnoconfig    gcc-15.2.0
i386                             allyesconfig    clang-20
i386        buildonly-randconfig-001-20260307    gcc-14
i386        buildonly-randconfig-002-20260307    gcc-14
i386        buildonly-randconfig-003-20260307    gcc-14
i386        buildonly-randconfig-004-20260307    gcc-14
i386        buildonly-randconfig-005-20260307    gcc-14
i386        buildonly-randconfig-006-20260307    gcc-14
i386                                defconfig    gcc-15.2.0
i386                  randconfig-001-20260307    clang-20
i386                  randconfig-002-20260307    clang-20
i386                  randconfig-003-20260307    clang-20
i386                  randconfig-004-20260307    clang-20
i386                  randconfig-005-20260307    clang-20
i386                  randconfig-006-20260307    clang-20
i386                  randconfig-007-20260307    clang-20
i386                  randconfig-011-20260307    gcc-14
i386                  randconfig-012-20260307    gcc-14
i386                  randconfig-013-20260307    gcc-14
i386                  randconfig-014-20260307    gcc-14
i386                  randconfig-015-20260307    gcc-14
i386                  randconfig-016-20260307    gcc-14
i386                  randconfig-017-20260307    gcc-14
loongarch                        allmodconfig    clang-23
loongarch                         allnoconfig    clang-23
loongarch                         allnoconfig    gcc-15.2.0
loongarch                           defconfig    clang-19
loongarch             randconfig-001-20260307    gcc-15.2.0
loongarch             randconfig-002-20260307    gcc-15.2.0
m68k                             allmodconfig    gcc-15.2.0
m68k                              allnoconfig    gcc-15.2.0
m68k                             allyesconfig    clang-16
m68k                             allyesconfig    gcc-15.2.0
m68k                                defconfig    clang-19
microblaze                        allnoconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-15.2.0
microblaze                          defconfig    clang-19
mips                             allmodconfig    gcc-15.2.0
mips                              allnoconfig    gcc-15.2.0
mips                             allyesconfig    gcc-15.2.0
nios2                            allmodconfig    clang-23
nios2                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-23
nios2                             allnoconfig    gcc-11.5.0
nios2                               defconfig    clang-19
nios2                 randconfig-001-20260307    gcc-15.2.0
nios2                 randconfig-002-20260307    gcc-15.2.0
openrisc                         allmodconfig    clang-23
openrisc                         allmodconfig    gcc-15.2.0
openrisc                          allnoconfig    clang-23
openrisc                          allnoconfig    gcc-15.2.0
openrisc                            defconfig    gcc-15.2.0
parisc                           allmodconfig    gcc-15.2.0
parisc                            allnoconfig    clang-23
parisc                            allnoconfig    gcc-15.2.0
parisc                           allyesconfig    clang-19
parisc                           allyesconfig    gcc-15.2.0
parisc                              defconfig    gcc-15.2.0
parisc                randconfig-001-20260307    gcc-12.5.0
parisc                randconfig-002-20260307    gcc-12.5.0
parisc64                            defconfig    clang-19
powerpc                          allmodconfig    gcc-15.2.0
powerpc                           allnoconfig    clang-23
powerpc                           allnoconfig    gcc-15.2.0
powerpc               randconfig-001-20260307    gcc-12.5.0
powerpc               randconfig-002-20260307    gcc-12.5.0
powerpc64             randconfig-001-20260307    gcc-12.5.0
powerpc64             randconfig-002-20260307    gcc-12.5.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-23
riscv                             allnoconfig    gcc-15.2.0
riscv                            allyesconfig    clang-16
riscv                               defconfig    gcc-15.2.0
riscv                 randconfig-001-20260307    clang-23
riscv                 randconfig-002-20260307    clang-23
s390                             allmodconfig    clang-18
s390                             allmodconfig    clang-19
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-15.2.0
s390                                defconfig    gcc-15.2.0
s390                  randconfig-001-20260307    clang-23
s390                  randconfig-002-20260307    clang-23
sh                               allmodconfig    gcc-15.2.0
sh                                allnoconfig    clang-23
sh                                allnoconfig    gcc-15.2.0
sh                               allyesconfig    clang-19
sh                               allyesconfig    gcc-15.2.0
sh                                  defconfig    gcc-14
sh                    randconfig-001-20260307    clang-23
sh                    randconfig-002-20260307    clang-23
sparc                             allnoconfig    clang-23
sparc                             allnoconfig    gcc-15.2.0
sparc                               defconfig    gcc-15.2.0
sparc                 randconfig-001-20260307    gcc-15.2.0
sparc                 randconfig-001-20260307    gcc-8.5.0
sparc                 randconfig-002-20260307    gcc-11.5.0
sparc                 randconfig-002-20260307    gcc-8.5.0
sparc64                          allmodconfig    clang-23
sparc64                             defconfig    gcc-14
sparc64               randconfig-001-20260307    clang-23
sparc64               randconfig-001-20260307    gcc-8.5.0
sparc64               randconfig-002-20260307    gcc-8.5.0
um                               allmodconfig    clang-19
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-15.2.0
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                    randconfig-001-20260307    gcc-14
um                    randconfig-001-20260307    gcc-8.5.0
um                    randconfig-002-20260307    clang-23
um                    randconfig-002-20260307    gcc-8.5.0
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-20
x86_64                            allnoconfig    clang-20
x86_64                            allnoconfig    clang-23
x86_64                           allyesconfig    clang-20
x86_64      buildonly-randconfig-001-20260307    clang-20
x86_64      buildonly-randconfig-002-20260307    clang-20
x86_64      buildonly-randconfig-003-20260307    clang-20
x86_64      buildonly-randconfig-004-20260307    clang-20
x86_64      buildonly-randconfig-005-20260307    clang-20
x86_64      buildonly-randconfig-006-20260307    clang-20
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-20
x86_64                randconfig-001-20260307    gcc-14
x86_64                randconfig-002-20260307    gcc-14
x86_64                randconfig-003-20260307    gcc-14
x86_64                randconfig-004-20260307    gcc-14
x86_64                randconfig-005-20260307    gcc-14
x86_64                randconfig-006-20260307    gcc-14
x86_64                randconfig-011-20260307    gcc-14
x86_64                randconfig-012-20260307    gcc-14
x86_64                randconfig-013-20260307    gcc-14
x86_64                randconfig-014-20260307    gcc-14
x86_64                randconfig-015-20260307    gcc-14
x86_64                randconfig-016-20260307    gcc-14
x86_64                randconfig-071-20260307    gcc-14
x86_64                randconfig-072-20260307    gcc-14
x86_64                randconfig-073-20260307    gcc-14
x86_64                randconfig-074-20260307    gcc-14
x86_64                randconfig-075-20260307    gcc-14
x86_64                randconfig-076-20260307    gcc-14
x86_64                               rhel-9.4    clang-20
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-20
x86_64                    rhel-9.4-kselftests    clang-20
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-20
xtensa                            allnoconfig    clang-23
xtensa                            allnoconfig    gcc-15.2.0
xtensa                randconfig-001-20260307    gcc-8.5.0
xtensa                randconfig-002-20260307    gcc-8.5.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [wireless:for-next] BUILD SUCCESS 6dccbc9f3e1d38565dff7730d2b7d1e8b16c9b09
From: kernel test robot @ 2026-03-07  5:25 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git for-next
branch HEAD: 6dccbc9f3e1d38565dff7730d2b7d1e8b16c9b09  wifi: cfg80211: cancel pmsr_free_wk in cfg80211_pmsr_wdev_down

elapsed time: 1037m

configs tested: 226
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig    gcc-15.2.0
alpha                            allyesconfig    gcc-15.2.0
alpha                               defconfig    gcc-15.2.0
arc                              allmodconfig    clang-16
arc                              allmodconfig    gcc-15.2.0
arc                               allnoconfig    gcc-15.2.0
arc                              allyesconfig    clang-23
arc                              allyesconfig    gcc-15.2.0
arc                                 defconfig    gcc-15.2.0
arc                   randconfig-001-20260307    gcc-14.3.0
arc                   randconfig-001-20260307    gcc-15.2.0
arc                   randconfig-002-20260307    gcc-14.3.0
arc                   randconfig-002-20260307    gcc-15.2.0
arm                               allnoconfig    clang-23
arm                               allnoconfig    gcc-15.2.0
arm                              allyesconfig    clang-16
arm                              allyesconfig    gcc-15.2.0
arm                        clps711x_defconfig    clang-23
arm                                 defconfig    gcc-15.2.0
arm                   randconfig-001-20260307    clang-23
arm                   randconfig-001-20260307    gcc-15.2.0
arm                   randconfig-002-20260307    gcc-15.2.0
arm                   randconfig-003-20260307    gcc-13.4.0
arm                   randconfig-003-20260307    gcc-15.2.0
arm                   randconfig-004-20260307    gcc-11.5.0
arm                   randconfig-004-20260307    gcc-15.2.0
arm64                            allmodconfig    clang-19
arm64                            allmodconfig    clang-23
arm64                             allnoconfig    gcc-15.2.0
arm64                               defconfig    gcc-15.2.0
arm64                 randconfig-001-20260307    gcc-8.5.0
arm64                 randconfig-002-20260307    gcc-11.5.0
arm64                 randconfig-002-20260307    gcc-8.5.0
arm64                 randconfig-003-20260307    gcc-15.2.0
arm64                 randconfig-003-20260307    gcc-8.5.0
arm64                 randconfig-004-20260307    gcc-8.5.0
csky                             allmodconfig    gcc-15.2.0
csky                              allnoconfig    gcc-15.2.0
csky                                defconfig    gcc-15.2.0
csky                  randconfig-001-20260307    gcc-15.2.0
csky                  randconfig-001-20260307    gcc-8.5.0
csky                  randconfig-002-20260307    gcc-15.2.0
csky                  randconfig-002-20260307    gcc-8.5.0
hexagon                          allmodconfig    clang-17
hexagon                          allmodconfig    gcc-15.2.0
hexagon                           allnoconfig    clang-23
hexagon                           allnoconfig    gcc-15.2.0
hexagon                             defconfig    gcc-15.2.0
hexagon               randconfig-001-20260307    clang-23
hexagon               randconfig-001-20260307    gcc-15.2.0
hexagon               randconfig-002-20260307    clang-23
hexagon               randconfig-002-20260307    gcc-15.2.0
i386                             allmodconfig    clang-20
i386                              allnoconfig    gcc-14
i386                              allnoconfig    gcc-15.2.0
i386                             allyesconfig    clang-20
i386        buildonly-randconfig-001-20260307    gcc-14
i386        buildonly-randconfig-002-20260307    gcc-14
i386        buildonly-randconfig-003-20260307    gcc-12
i386        buildonly-randconfig-003-20260307    gcc-14
i386        buildonly-randconfig-004-20260307    clang-20
i386        buildonly-randconfig-004-20260307    gcc-14
i386        buildonly-randconfig-005-20260307    gcc-14
i386        buildonly-randconfig-006-20260307    clang-20
i386        buildonly-randconfig-006-20260307    gcc-14
i386                                defconfig    gcc-15.2.0
i386                  randconfig-001-20260307    clang-20
i386                  randconfig-002-20260307    clang-20
i386                  randconfig-003-20260307    clang-20
i386                  randconfig-004-20260307    clang-20
i386                  randconfig-005-20260307    clang-20
i386                  randconfig-006-20260307    clang-20
i386                  randconfig-007-20260307    clang-20
i386                  randconfig-011-20260307    clang-20
i386                  randconfig-011-20260307    gcc-14
i386                  randconfig-012-20260307    clang-20
i386                  randconfig-012-20260307    gcc-14
i386                  randconfig-013-20260307    clang-20
i386                  randconfig-013-20260307    gcc-14
i386                  randconfig-014-20260307    clang-20
i386                  randconfig-014-20260307    gcc-14
i386                  randconfig-015-20260307    gcc-14
i386                  randconfig-016-20260307    gcc-14
i386                  randconfig-017-20260307    gcc-14
loongarch                        allmodconfig    clang-19
loongarch                        allmodconfig    clang-23
loongarch                         allnoconfig    clang-23
loongarch                         allnoconfig    gcc-15.2.0
loongarch                           defconfig    clang-19
loongarch             randconfig-001-20260307    gcc-15.2.0
loongarch             randconfig-002-20260307    gcc-15.2.0
m68k                             allmodconfig    gcc-15.2.0
m68k                              allnoconfig    gcc-15.2.0
m68k                             allyesconfig    clang-16
m68k                             allyesconfig    gcc-15.2.0
m68k                                defconfig    clang-19
microblaze                        allnoconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-15.2.0
microblaze                          defconfig    clang-19
mips                             allmodconfig    gcc-15.2.0
mips                              allnoconfig    gcc-15.2.0
mips                             allyesconfig    gcc-15.2.0
nios2                            allmodconfig    clang-23
nios2                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-23
nios2                             allnoconfig    gcc-11.5.0
nios2                               defconfig    clang-19
nios2                 randconfig-001-20260307    gcc-10.5.0
nios2                 randconfig-001-20260307    gcc-15.2.0
nios2                 randconfig-002-20260307    gcc-15.2.0
nios2                 randconfig-002-20260307    gcc-8.5.0
openrisc                         allmodconfig    clang-23
openrisc                         allmodconfig    gcc-15.2.0
openrisc                          allnoconfig    clang-23
openrisc                          allnoconfig    gcc-15.2.0
openrisc                            defconfig    gcc-15.2.0
parisc                           allmodconfig    gcc-15.2.0
parisc                            allnoconfig    clang-23
parisc                            allnoconfig    gcc-15.2.0
parisc                           allyesconfig    clang-19
parisc                           allyesconfig    gcc-15.2.0
parisc                              defconfig    gcc-15.2.0
parisc                randconfig-001-20260307    gcc-12.5.0
parisc                randconfig-002-20260307    gcc-12.5.0
parisc                randconfig-002-20260307    gcc-8.5.0
parisc64                            defconfig    clang-19
powerpc                          allmodconfig    gcc-15.2.0
powerpc                           allnoconfig    clang-23
powerpc                           allnoconfig    gcc-15.2.0
powerpc               randconfig-001-20260307    gcc-12.5.0
powerpc               randconfig-001-20260307    gcc-8.5.0
powerpc               randconfig-002-20260307    gcc-11.5.0
powerpc               randconfig-002-20260307    gcc-12.5.0
powerpc64             randconfig-001-20260307    gcc-12.5.0
powerpc64             randconfig-001-20260307    gcc-8.5.0
powerpc64             randconfig-002-20260307    gcc-12.5.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-23
riscv                             allnoconfig    gcc-15.2.0
riscv                            allyesconfig    clang-16
riscv                               defconfig    gcc-15.2.0
riscv                 randconfig-001-20260307    clang-23
riscv                 randconfig-002-20260307    clang-23
s390                             allmodconfig    clang-18
s390                             allmodconfig    clang-19
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-15.2.0
s390                                defconfig    gcc-15.2.0
s390                  randconfig-001-20260307    clang-23
s390                  randconfig-002-20260307    clang-23
sh                               allmodconfig    gcc-15.2.0
sh                                allnoconfig    clang-23
sh                                allnoconfig    gcc-15.2.0
sh                               allyesconfig    clang-19
sh                               allyesconfig    gcc-15.2.0
sh                                  defconfig    gcc-14
sh                    randconfig-001-20260307    clang-23
sh                    randconfig-002-20260307    clang-23
sparc                             allnoconfig    clang-23
sparc                             allnoconfig    gcc-15.2.0
sparc                               defconfig    gcc-15.2.0
sparc                 randconfig-001-20260307    gcc-15.2.0
sparc                 randconfig-001-20260307    gcc-8.5.0
sparc                 randconfig-002-20260307    gcc-11.5.0
sparc                 randconfig-002-20260307    gcc-8.5.0
sparc64                          allmodconfig    clang-23
sparc64                             defconfig    gcc-14
sparc64               randconfig-001-20260307    clang-23
sparc64               randconfig-001-20260307    gcc-8.5.0
sparc64               randconfig-002-20260307    gcc-8.5.0
um                               allmodconfig    clang-19
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-14
um                               allyesconfig    gcc-15.2.0
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                    randconfig-001-20260307    gcc-14
um                    randconfig-001-20260307    gcc-8.5.0
um                    randconfig-002-20260307    clang-23
um                    randconfig-002-20260307    gcc-8.5.0
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-20
x86_64                            allnoconfig    clang-20
x86_64                            allnoconfig    clang-23
x86_64                           allyesconfig    clang-20
x86_64      buildonly-randconfig-001-20260307    clang-20
x86_64      buildonly-randconfig-001-20260307    gcc-14
x86_64      buildonly-randconfig-002-20260307    clang-20
x86_64      buildonly-randconfig-002-20260307    gcc-14
x86_64      buildonly-randconfig-003-20260307    clang-20
x86_64      buildonly-randconfig-003-20260307    gcc-14
x86_64      buildonly-randconfig-004-20260307    clang-20
x86_64      buildonly-randconfig-005-20260307    clang-20
x86_64      buildonly-randconfig-006-20260307    clang-20
x86_64      buildonly-randconfig-006-20260307    gcc-14
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-20
x86_64                randconfig-001-20260307    gcc-14
x86_64                randconfig-002-20260307    gcc-14
x86_64                randconfig-003-20260307    gcc-14
x86_64                randconfig-004-20260307    gcc-14
x86_64                randconfig-005-20260307    gcc-14
x86_64                randconfig-006-20260307    gcc-14
x86_64                randconfig-011-20260307    gcc-14
x86_64                randconfig-012-20260307    gcc-14
x86_64                randconfig-013-20260307    gcc-14
x86_64                randconfig-014-20260307    gcc-14
x86_64                randconfig-015-20260307    gcc-14
x86_64                randconfig-016-20260307    gcc-14
x86_64                randconfig-071-20260307    gcc-14
x86_64                randconfig-072-20260307    gcc-14
x86_64                randconfig-073-20260307    gcc-14
x86_64                randconfig-074-20260307    gcc-14
x86_64                randconfig-075-20260307    gcc-14
x86_64                randconfig-076-20260307    gcc-14
x86_64                               rhel-9.4    clang-20
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-20
x86_64                    rhel-9.4-kselftests    clang-20
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-20
xtensa                            allnoconfig    clang-23
xtensa                            allnoconfig    gcc-15.2.0
xtensa                randconfig-001-20260307    gcc-8.5.0
xtensa                randconfig-002-20260307    gcc-8.5.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH 00/18] wifi: mt76: mt7925: add MT7927 (Filogic 380) support
From: Sean Wang @ 2026-03-07  7:08 UTC (permalink / raw)
  To: Javier Tia
  Cc: linux-wireless, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
	Shayne Chen, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Deren Wu, Ming Yen Hsieh,
	linux-kernel, linux-arm-kernel, linux-mediatek, Marcin FM,
	Cristian-Florin Radoi, George Salukvadze, Evgeny Kapusta,
	Samu Toljamo, Ariel Rosenfeld, Chapuis Dario,
	Thibaut François, 张旭涵
In-Reply-To: <20260306-mt7927-wifi-support-v1-0-c77e7445511d@jetm.me>

Hi Javier,

On Fri, Mar 6, 2026 at 6:33 PM Javier Tia <floss@jetm.me> wrote:
>
> This series adds support for the MediaTek MT7927 (Filogic 380) combo
> WiFi 7 + BT 5.4 module to the mt7925 driver. The MT7927 uses PCI ID
> 14c3:7927 (some hardware reports 14c3:6639) and shares the mt7925
> firmware interface but requires different DMA ring layout, IRQ mapping,
> chip initialization, and power management handling.
>
> Tested hardware:
> - ASUS ROG Crosshair X870E Hero (BT 0489:e13a, WiFi 14c3:6639)
> - ASUS ProArt X870E-Creator WiFi (BT 0489:e13a / 13d3:3588, WiFi 14c3:6639)
> - ASUS ROG Strix X870E-E (BT 0489:e13a, WiFi 14c3:7927)
> - Gigabyte X870E Aorus Master X3D (BT 0489:e10f, WiFi 14c3:7927)
> - Gigabyte Z790 AORUS MASTER X (BT 0489:e10f, WiFi 14c3:7927)
> - Lenovo Legion Pro 7 16ARX9 (BT 0489:e0fa, WiFi 14c3:7927)
> - TP-Link Archer TBE550E PCIe (BT 0489:e116, WiFi 14c3:7927)
> - EDUP EP-MT7927BE M.2 card (WiFi 14c3:7927)
> - Foxconn/Azurewave M.2 modules (WiFi 14c3:6639)
> - AMD RZ738 reference design (WiFi 14c3:0738)
>

Thanks for coordinating the work and delivering the driver.

> Tested on Arch Linux, CachyOS, EndeavourOS, Fedora (Bazzite), NixOS,
> openSUSE Tumbleweed, and Ubuntu across kernels 6.13-6.19.
>
> What works:
> - WiFi 7 with EHT 320MHz on 2.4/5/6 GHz bands
> - 320MHz data path verified at 841 Mbps (iperf3 -t30 -P8)
> - PCIe initialization with CBTOP remap and MT7927-specific DMA layout
> - Runtime power management and suspend/resume (S3)
> - DBDC (dual-band concurrent) mode
> - Explicit band_idx assignment for stable 5GHz/6GHz operation
> - ASPM disabled for MT7927 to prevent throughput collapse
>
> Known limitations (planned as follow-up series):
> - MLO (Multi-Link Operation): tested working on 5GHz+2.4GHz STR
>   (776 Mbps) but requires additional patches for link lifetime
>   and error handling. Sean Wang's series [1] addresses these;
>   MLO support will be submitted as a follow-up on top of that.
>
> [1] https://lore.kernel.org/linux-wireless/20260306232238.2039675-1-sean.wang@kernel.org/
> - TX retransmissions: elevated retry rate on all bands, firmware-side
>   rate adaptation issue not addressable in the driver.
>
> Patches 1-11 bring up the basic driver (chip ID, firmware, DMA, init,
> power management, 320MHz MCS, mac_reset guard, IRQ map, probe fix).
> Patch 12 advertises EHT 320MHz capabilities, guarded by is_mt7927().
> Patches 13-14 fix DMASHDL PM wake and disable ASPM.
> Patch 15 adds 320MHz bandwidth handling in RXV/TXS status reporting.
> Patch 16 fixes stale pointer comparisons in change_vif_links.
> Patch 17 assigns explicit band_idx for stable 5GHz/6GHz operation.
> Patch 18 adds the missing 320MHz case in bss_rlm_tlv() so firmware
> receives the correct bandwidth when associated to a 320MHz BSS.
>
> The WiFi firmware ships as part of the linux-firmware package
> (mediatek/mt6639/ directory - the firmware uses the mobile SoC codename).
>
> To: linux-wireless@vger.kernel.org
> To: Felix Fietkau <nbd@nbd.name>
> To: Lorenzo Bianconi <lorenzo@kernel.org>
> To: Ryder Lee <ryder.lee@mediatek.com>
> To: Shayne Chen <shayne.chen@mediatek.com>
> To: Sean Wang <sean.wang@mediatek.com>
> To: Matthias Brugger <matthias.bgg@gmail.com>
> To: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> To: Deren Wu <deren.wu@mediatek.com>
> To: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-mediatek@lists.infradead.org
> Tested-by: Marcin FM <marcin@lgic.pl>
> Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
> Tested-by: George Salukvadze <giosal90@gmail.com>
> Tested-by: Evgeny Kapusta <3193631@gmail.com>
> Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
> Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
> Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
> Tested-by: Thibaut François <tibo@humeurlibre.fr>
> Tested-by: 张旭涵 <Loong.0x00@gmail.com>
>
> Signed-off-by: Javier Tia <floss@jetm.me>
> ---
> Javier Tia (18):
>       wifi: mt76: mt7925: add MT7927 chip ID helpers
>       wifi: mt76: mt7925: add MT7927 firmware paths and PCI device IDs
>       wifi: mt76: mt7925: add MT7927 CBTOP remap and chip initialization
>       wifi: mt76: mt7925: add MT7927 DMA ring layout, IRQ map, and prefetch
>       wifi: mt76: mt7925: skip CLR_OWN in mt7925e_mcu_init for MT7927
>       wifi: mt76: mt7925: add MT7927 power management, DBDC, and CNM fixes
>       wifi: mt76: mt7925: use irq_map fields instead of MT_INT_RX_DONE_ALL
>       wifi: mt76: mt7925: guard mac_reset against MT7927 DMA destruction
>       wifi: mt76: mt7925: populate EHT 320MHz MCS map in sta_rec
>       wifi: mt76: mt7925: enable MT7927 runtime power management
>       wifi: mt76: mt7925: fix uninitialized is_mt7927_hw in probe
>       wifi: mt76: mt7925: advertise EHT 320MHz capabilities for 6GHz band
>       wifi: mt76: mt7925: restore FW_DWLD_BYPASS_DMASHDL in MT7927 PM wake path
>       wifi: mt76: mt7925: disable ASPM for MT7927 to fix throughput collapse
>       wifi: mt76: mt7925: handle 320MHz bandwidth in RXV and TXS
>       wifi: mt76: mt7925: fix stale pointer comparisons in change_vif_links
>       wifi: mt76: mt7925: fix MT7927 band_idx for stable 5GHz/6GHz operation
>       wifi: mt76: mt7925: add 320MHz bandwidth to bss_rlm_tlv
>

The patchset should be ordered so that common changes (e.g., enabling
320 MHz support) are added first,
while chip-specific changes are introduced later (e.g.,
MT7927-specific IRQ, DMA, and hardware initialization sequences).
Before introducing chip-specific logic, try to make the functions
generic enough so that other chips can reuse them in the same way.
Checks such as is_mt7927 and duplicated function should only be added
if they cannot be avoided

The more code we can reuse across chips, the fewer maintenance
concerns there will be, and we can focus more effort on the
chip-specific parts.

Please reorganize the patchset order as follows:

1. Common patches that can be reused by other chipsets (now or in the
future) should come first we don't need to mention mt7927

"wifi: mt76: mt7925: fix stale pointer comparisons in change_vif_links"
"wifi: mt76: mt7925: add 320MHz bandwidth to bss_rlm_tlv"
"wifi: mt76: mt7925: handle 320MHz bandwidth in RXV and TXS"
"wifi: mt76: mt7925: populate EHT 320MHz MCS map in sta_rec"
"wifi: mt76: mt7925: advertise EHT 320MHz capabilities for 6GHz band"

Here we can add a helper like is_320MHz_supported() and then advertise
EHT 320MHz capabilities, but do not need to mention is_mt7927() yet.

2. Then introduce MT7927-related changes

wifi: mt76: mt7925: add MT7927 chip ID helpers
Keep the MCU part of "wifi: mt76: mt7925: add MT7927 firmware paths
and PCI device IDs" but leave enabling the PCI device table for the
last patch.

3. IRQ handling

Combine

wifi: mt76: mt7925: use irq_map fields instead of MT_INT_RX_DONE_ALL
the IRQ part of wifi: mt76: mt7925: add MT7927 DMA ring layout, IRQ
map, and prefetch
into one patch about irq_map handling, trying to reuse mt7925_irq as
much as possible.

4. DMA handling

Combine

the DMA part of "wifi: mt76: mt7925: add MT7927 DMA ring layout, IRQ
map, and prefetch"
"wifi: mt76: mt7925: restore FW_DWLD_BYPASS_DMASHDL in MT7927 PM wake path"
into one patch about DMA handling, trying to reuse mt7925_dma_init as
much as possible.

5. Hardware initialization

Combine

"wifi: mt76: mt7925: add MT7927 CBTOP remap and chip initialization"
"wifi: mt76: mt7925: fix uninitialized is_mt7927_hw in probe"
"wifi: mt76: mt7925: skip CLR_OWN in mt7925e_mcu_init for MT7927"
"wifi: mt76: mt7925: add MT7927 power management, DBDC, and CNM fixes"

into one or more patches focused on pure hardware initialization in
logical order. If the register definition is used by MT7927, add
MT7927_ as the prefix.

6. Band index fix

"wifi: mt76: mt7925: fix MT7927 band_idx for stable 5GHz/6GHz operation"
This is worth introducing helper functions and using them instead of
implementing the logic inline.

7. Low power support

Combine

"wifi: mt76: mt7925: enable MT7927 runtime power management"
"wifi: mt76: mt7925: disable ASPM for MT7927 to fix throughput collapse"

into one or more patches related to enabling or disabling low power support.

8. Final patch
The last patch should enable the MT7927 PCI device table.

>  drivers/net/wireless/mediatek/mt76/mt76_connac.h   |   8 +-
>  drivers/net/wireless/mediatek/mt76/mt7925/init.c   |  12 +
>  drivers/net/wireless/mediatek/mt76/mt7925/mac.c    |   9 +
>  drivers/net/wireless/mediatek/mt76/mt7925/main.c   |  72 +++++-
>  drivers/net/wireless/mediatek/mt76/mt7925/mcu.c    |  59 ++++-
>  drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h |  12 +
>  drivers/net/wireless/mediatek/mt76/mt7925/pci.c    | 248 ++++++++++++++++++++-
>  .../net/wireless/mediatek/mt76/mt7925/pci_mac.c    |  13 +-
>  .../net/wireless/mediatek/mt76/mt7925/pci_mcu.c    |  19 +-
>  drivers/net/wireless/mediatek/mt76/mt792x.h        |   6 +
>  drivers/net/wireless/mediatek/mt76/mt792x_dma.c    |  26 ++-
>  drivers/net/wireless/mediatek/mt76/mt792x_regs.h   |  30 +++
>  12 files changed, 479 insertions(+), 35 deletions(-)
> ---
> base-commit: 97492c019da4b62df83255e968b23b81c0315530
> change-id: 20260305-mt7927-wifi-support-02f9738a3962
>
> Best regards,
> --
> Javier Tia <floss@jetm.me>
>
>

^ permalink raw reply

* New Shipment Notifications
From: DHL Express @ 2026-03-07 13:24 UTC (permalink / raw)
  To: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 514 bytes --]

Dear Customer,

Your DHL shipment is ready for dispatch, or there was a failed delivery attempt. Please track your shipment and take any necessary steps to ensure successful delivery.

You can find the shipment information in the attached file.

We look forward to assisting you with your shipping needs!

If you need to contact us in the meantime, please get in touch with our customer service.

Sincerely,

Your MyDHL+ Team

Please do not reply to this email – the inbox is not checked regularly.

[-- Attachment #2: Shipment Notification 1.pdf --]
[-- Type: application/pdf, Size: 98916 bytes --]

^ permalink raw reply

* Re: [PATCH 02/19] wifi: mt76: mt7925: pass WCID indices to bss_basic_tlv()
From: kernel test robot @ 2026-03-07 13:45 UTC (permalink / raw)
  To: Sean Wang, nbd, lorenzo.bianconi
  Cc: oe-kbuild-all, linux-wireless, linux-mediatek, Sean Wang
In-Reply-To: <20260306232238.2039675-3-sean.wang@kernel.org>

Hi Sean,

kernel test robot noticed the following build warnings:

[auto build test WARNING on wireless-next/main]
[also build test WARNING on wireless/main linus/master v7.0-rc2 next-20260306]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Sean-Wang/wifi-mt76-mt7925-pass-mlink-to-sta_amsdu_tlv/20260307-073047
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
patch link:    https://lore.kernel.org/r/20260306232238.2039675-3-sean.wang%40kernel.org
patch subject: [PATCH 02/19] wifi: mt76: mt7925: pass WCID indices to bss_basic_tlv()
config: x86_64-rhel-9.4 (https://download.01.org/0day-ci/archive/20260307/202603071400.xCvjvPoG-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260307/202603071400.xCvjvPoG-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603071400.xCvjvPoG-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/net/wireless/mediatek/mt76/mt7925/mcu.c: In function 'mt7925_mcu_add_bss_info':
>> drivers/net/wireless/mediatek/mt76/mt7925/mcu.c:2867:13: warning: variable 'sta_wlan_idx' set but not used [-Wunused-but-set-variable]
    2867 |         u16 sta_wlan_idx;
         |             ^~~~~~~~~~~~


vim +/sta_wlan_idx +2867 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c

  2856	
  2857	int mt7925_mcu_add_bss_info(struct mt792x_phy *phy,
  2858				    struct ieee80211_chanctx_conf *ctx,
  2859				    struct ieee80211_bss_conf *link_conf,
  2860				    struct ieee80211_link_sta *link_sta,
  2861				    int enable)
  2862	{
  2863		struct mt792x_vif *mvif = (struct mt792x_vif *)link_conf->vif->drv_priv;
  2864		struct mt792x_bss_conf *mconf = mt792x_link_conf_to_mconf(link_conf);
  2865		struct mt792x_link_sta *mlink_bc;
  2866		struct mt792x_link_sta *mlink;
> 2867		u16 sta_wlan_idx;
  2868	
  2869		sta_wlan_idx = mvif->sta.deflink.wcid.idx;
  2870	
  2871		mlink_bc = mt792x_sta_to_link(&mvif->sta, mconf->link_id);
  2872	
  2873		if (link_sta) {
  2874			struct mt792x_sta *msta = (void *)link_sta->sta->drv_priv;
  2875	
  2876			mlink = mt792x_sta_to_link(msta, link_sta->link_id);
  2877			if (WARN_ON(!mlink))
  2878				return -1;
  2879		} else {
  2880			mlink = &mconf->vif->sta.deflink;
  2881		}
  2882	
  2883		return mt7925_mcu_add_bss_info_sta(phy, ctx, link_conf, link_sta,
  2884						   mlink_bc->wcid.idx, mlink->wcid.idx, enable);
  2885	}
  2886	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH mt76] wifi: mt76: mt7996: Switch deflink to seclink only if link lookup does not fail
From: Lorenzo Bianconi @ 2026-03-07 13:59 UTC (permalink / raw)
  To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
	Lorenzo Bianconi

Do not switch default link to the secondary link in
mt7996_mac_sta_remove_links routine if the lookup for the secondary
msta_link fails.

Fixes: d7e5444f9eb02 ("wifi: mt76: mt7996: Switch to the secondary link if the default one is removed")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7996/main.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index e1e51c9a0767be5a15dae48d627fb45b6f12af21..00e0e5915afe32b70205f1128f32a07ac02223e8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -1122,21 +1122,22 @@ mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
 
 		mphy->num_sta--;
 		if (msta->deflink_id == link_id) {
-			if (msta->seclink_id == msta->deflink_id) {
+			msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
+			if (msta->seclink_id == link_id) {
 				/* no secondary link available */
-				msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
 				msta->seclink_id = msta->deflink_id;
 			} else {
 				struct mt7996_sta_link *msta_seclink;
 
 				/* switch to the secondary link */
-				msta->deflink_id = msta->seclink_id;
 				msta_seclink = mt76_dereference(
 						msta->link[msta->seclink_id],
 						mdev);
-				if (msta_seclink)
+				if (msta_seclink) {
+					msta->deflink_id = msta->seclink_id;
 					mt7996_sta_init_txq_wcid(sta,
 						msta_seclink->wcid.idx);
+				}
 			}
 		} else if (msta->seclink_id == link_id) {
 			msta->seclink_id = msta->deflink_id;

---
base-commit: 030eea77accf40477be540445fc5a5be52d810a3
change-id: 20260307-mt7996-sta-sec-link-fix-7d6d49e56eb4

Best regards,
-- 
Lorenzo Bianconi <lorenzo@kernel.org>


^ permalink raw reply related

* [PATCH] wifi: b43: use register definitions in nphy_op_software_rfkill
From: Joshua Peisach @ 2026-03-07 17:01 UTC (permalink / raw)
  To: linux-wireless, b43-dev
  Cc: Johan Hovold, Francesco Dolcini, Johannes Berg, Joshua Peisach

Replaces uses of hardcoded register addresses with proper definitions,
for readability.

Signed-off-by: Joshua Peisach <jpeisach@ubuntu.com>
---
 drivers/net/wireless/broadcom/b43/phy_n.c | 26 +++++++++++------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c
index bbc30cbad..22359bd9d 100644
--- a/drivers/net/wireless/broadcom/b43/phy_n.c
+++ b/drivers/net/wireless/broadcom/b43/phy_n.c
@@ -6566,19 +6566,19 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
 
 			b43_radio_mask(dev, 0x09, ~0x2);
 
-			b43_radio_write(dev, 0x204D, 0);
-			b43_radio_write(dev, 0x2053, 0);
-			b43_radio_write(dev, 0x2058, 0);
-			b43_radio_write(dev, 0x205E, 0);
-			b43_radio_mask(dev, 0x2062, ~0xF0);
-			b43_radio_write(dev, 0x2064, 0);
-
-			b43_radio_write(dev, 0x304D, 0);
-			b43_radio_write(dev, 0x3053, 0);
-			b43_radio_write(dev, 0x3058, 0);
-			b43_radio_write(dev, 0x305E, 0);
-			b43_radio_mask(dev, 0x3062, ~0xF0);
-			b43_radio_write(dev, 0x3064, 0);
+			b43_radio_write(dev, B2056_TX0 | B2056_TX_PADA_BOOST_TUNE, 0);
+			b43_radio_write(dev, B2056_TX0 | B2056_TX_PADG_BOOST_TUNE, 0);
+			b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAA_BOOST_TUNE, 0);
+			b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAG_BOOST_TUNE, 0);
+			b43_radio_mask(dev, B2056_TX0 | B2056_TX_MIXA_BOOST_TUNE, ~0xF0);
+			b43_radio_write(dev, B2056_TX0 | B2056_TX_MIXG_BOOST_TUNE, 0);
+
+			b43_radio_write(dev, B2056_TX1 | B2056_TX_PADA_BOOST_TUNE, 0);
+			b43_radio_write(dev, B2056_TX1 | B2056_TX_PADG_BOOST_TUNE, 0);
+			b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAA_BOOST_TUNE, 0);
+			b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAG_BOOST_TUNE, 0);
+			b43_radio_mask(dev, B2056_TX1 | B2056_TX_MIXA_BOOST_TUNE, ~0xF0);
+			b43_radio_write(dev, B2056_TX1 | B2056_TX_MIXG_BOOST_TUNE, 0);
 		}
 	} else {
 		if (phy->rev >= 19) {
-- 
2.51.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox