[PATCH 13/20] wifi: mt76: mt7925: add MT7928 FWDL support

JB Tsai jb.tsai at mediatek.com
Fri Jun 12 00:53:11 PDT 2026


From: Emery Hsin <emery.hsin at mediatek.com>

Add CBMCU and PHY RAM firmware download flow for MT7928. The CBMCU
firmware is loaded in sections before the main WM firmware. Register
MT7928 firmware file names and is_mt7928() chip check.

Signed-off-by: FC Wei <fc.wei at mediatek.com>
Signed-off-by: Xiong <xiong.huang at mediatek.com>
Signed-off-by: Emery Hsin <emery.hsin at mediatek.com>
---
 .../net/wireless/mediatek/mt76/mt76_connac.h  |   7 +-
 .../wireless/mediatek/mt76/mt76_connac_mcu.c  | 251 +++++++++++++++++-
 .../wireless/mediatek/mt76/mt76_connac_mcu.h  |  40 +++
 .../net/wireless/mediatek/mt76/mt7925/mcu.c   |  15 +-
 drivers/net/wireless/mediatek/mt76/mt792x.h   |  29 ++
 .../net/wireless/mediatek/mt76/mt792x_core.c  |  15 ++
 6 files changed, 353 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
index 2aa6078993e9..e21c393bb26d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
@@ -174,7 +174,7 @@ extern const struct wiphy_wowlan_support mt76_connac_wowlan_support;
 
 static inline bool is_connac3(struct mt76_dev *dev)
 {
-	return mt76_chip(dev) == 0x7925 || mt76_chip(dev) == 0x7927;
+	return mt76_chip(dev) == 0x7925 || mt76_chip(dev) == 0x7927 || mt76_chip(dev) == 0x7928;
 }
 
 static inline bool is_mt7925(struct mt76_dev *dev)
@@ -187,6 +187,11 @@ static inline bool is_mt7927(struct mt76_dev *dev)
 	return mt76_chip(dev) == 0x7927;
 }
 
+static inline bool is_mt7928(struct mt76_dev *dev)
+{
+	return mt76_chip(dev) == 0x7928;
+}
+
 static inline bool is_320mhz_supported(struct mt76_dev *dev)
 {
 	return mt76_chip(dev) == 0x7927;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 6596c9e198f4..488fe5ef3fbc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -67,7 +67,8 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
 
 	if ((!is_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) ||
 	    (is_connac2(dev) && addr == 0x900000) ||
-	    (is_connac3(dev) && (addr == 0x900000 || addr == 0xe0002800)) ||
+	    ((is_mt7925(dev) || is_mt7927(dev)) && (addr == 0x900000 || addr == 0xe0002800)) ||
+	    (is_mt7928(dev) && (addr == 0x900000 || addr == 0xe0002000)) ||
 	    (is_mt799x(dev) && addr == 0x900000))
 		cmd = MCU_CMD(PATCH_START_REQ);
 	else
@@ -77,6 +78,48 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
 }
 EXPORT_SYMBOL_GPL(mt76_connac_mcu_init_download);
 
+int mt76_connac_cb_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get)
+{
+	u8 op = get ? PATCH_SEM_GET : PATCH_SEM_RELEASE;
+	struct {
+		u8 op;
+		u8 reserved[3];
+	} req = {
+		.op = op,
+	};
+
+	return mt76_mcu_send_msg(dev, MCU_CMD(CB_PATCH_SEM_CONTROL),
+				 &req, sizeof(req), true);
+}
+EXPORT_SYMBOL_GPL(mt76_connac_cb_mcu_patch_sem_ctrl);
+
+int mt76_connac_cb_mcu_start_patch(struct mt76_dev *dev)
+{
+	struct {
+		__le32 reserved;
+	} req = {
+		.reserved = 0,
+	};
+
+	return mt76_mcu_send_msg(dev, MCU_CMD(CB_PATCH_FINISH_REQ),
+				 &req, sizeof(req), true);
+}
+EXPORT_SYMBOL_GPL(mt76_connac_cb_mcu_start_patch);
+
+int mt76_connac_cb_mcu_init_download(struct mt76_dev *dev, u32 len)
+{
+	struct {
+		__le32 addr;
+		__le32 len;
+	} req = {
+		.addr = 0, /* addr is meaningless for cbmcu fwdl */
+		.len = cpu_to_le32(len),
+	};
+
+	return mt76_mcu_send_msg(dev, MCU_CMD(CB_PATCH_START_REQ), &req, sizeof(req), true);
+}
+EXPORT_SYMBOL_GPL(mt76_connac_cb_mcu_init_download);
+
 int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy)
 {
 	int len, i, n_max_channels, n_2ch = 0, n_5ch = 0, n_6ch = 0;
@@ -3042,6 +3085,57 @@ mt76_connac_mcu_send_ram_firmware(struct mt76_dev *dev,
 	return mt76_connac_mcu_start_firmware(dev, override, option);
 }
 
+static int
+mt76_connac_mcu_send_phy_ram_firmware(struct mt76_dev *dev,
+				      const struct mt76_connac2_fw_trailer *hdr,
+				      const u8 *data)
+{
+	int i, offset = 0, max_len = mt76_is_sdio(dev) ? 2048 : 4096;
+	u32 override = 0, option = 0;
+
+	for (i = 0; i < hdr->n_region; i++) {
+		const struct mt76_connac2_fw_region *region;
+		u32 len, addr, mode;
+		int err;
+
+		region = (const void *)((const u8 *)hdr -
+					(hdr->n_region - i) * sizeof(*region));
+		mode = mt76_connac_mcu_gen_dl_mode(dev, region->feature_set,
+						   true);
+		len = le32_to_cpu(region->len);
+		addr = le32_to_cpu(region->addr);
+
+		if (region->feature_set & FW_FEATURE_NON_DL)
+			goto next;
+
+		if (region->feature_set & FW_FEATURE_OVERRIDE_ADDR)
+			override = addr;
+
+		err = mt76_connac_mcu_init_download(dev, addr, len, mode);
+		if (err) {
+			dev_err(dev->dev,
+				"The request to dowload PHY firmware failed.\n");
+			return err;
+		}
+
+		err = __mt76_mcu_send_firmware(dev, MCU_CMD(FW_SCATTER),
+					       data + offset, len, max_len);
+		if (err) {
+			dev_err(dev->dev, "Failed to send PHY firmware.\n");
+			return err;
+		}
+
+next:
+		offset += len;
+	}
+
+	if (override)
+		option |= FW_START_OVERRIDE;
+	option |= FW_START_WORKING_PDA_DSP;
+
+	return mt76_connac_mcu_start_firmware(dev, override, option);
+}
+
 int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
 			  const char *fw_wa)
 {
@@ -3109,6 +3203,39 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
 }
 EXPORT_SYMBOL_GPL(mt76_connac2_load_ram);
 
+int mt76_connac3_load_phy_ram(struct mt76_dev *dev, const char *fw_name)
+{
+	const struct mt76_connac2_fw_trailer *hdr;
+	const struct firmware *fw;
+	int ret;
+
+	ret = request_firmware(&fw, fw_name, dev->dev);
+	if (ret)
+		return ret;
+
+	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
+		dev_err(dev->dev, "Invalid PHY firmware\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
+	dev_info(dev->dev, "PHY Firmware Version: %.10s, Build Time: %.15s\n",
+		 hdr->fw_ver, hdr->build_date);
+
+	ret = mt76_connac_mcu_send_phy_ram_firmware(dev, hdr, fw->data);
+	if (ret) {
+		dev_err(dev->dev, "Failed to start PHY firmware\n");
+		goto out;
+	}
+
+out:
+	release_firmware(fw);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mt76_connac3_load_phy_ram);
+
 static u32 mt76_connac2_get_data_mode(struct mt76_dev *dev, u32 info)
 {
 	u32 mode = DL_MODE_NEED_RSP;
@@ -3222,6 +3349,128 @@ int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
 }
 EXPORT_SYMBOL_GPL(mt76_connac2_load_patch);
 
+int mt76_connac3_load_cb_patch(struct mt76_dev *dev, const char *fw_name)
+{
+	const struct mt76_connac3_multi_header_v2_sec_raw_format *sect = NULL;
+	const struct mt76_connac3_multi_header_v2_raw_format *hdr = NULL;
+	int i, ret, sem, max_len = mt76_is_sdio(dev) ? 2048 : 4096;
+	const struct firmware *fw = NULL;
+	const u8 *dl;
+	u32 len;
+
+	sem = mt76_connac_cb_mcu_patch_sem_ctrl(dev, true);
+	switch (sem) {
+	case CB_PATCH_IS_DL:
+		return 0;
+	case CB_PATCH_GET_SEM_NEED_PATCH:
+		break;
+	default:
+		dev_err(dev->dev, "Failed to get cb patch semaphore %u\n", sem);
+		return -EAGAIN;
+	}
+
+	ret = request_firmware(&fw, fw_name, dev->dev);
+	if (ret)
+		goto out;
+
+	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
+		dev_err(dev->dev, "Invalid firmware\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	hdr = (const void *)fw->data;
+	dev_info(dev->dev, "HW/SW Version: 0x%x, Pack Time: %.21s\n",
+		 le32_to_cpu(hdr->patch_ver), hdr->pack_time);
+
+	if (le32_to_cpu(hdr->sec_num) < 2) {
+		dev_err(dev->dev, "Invalid section numbers %u\n",
+			le32_to_cpu(hdr->sec_num));
+		ret = -EINVAL;
+		goto out;
+	}
+
+	sect = &hdr->sects[0];
+	/* check the fw bin basic info */
+	if (((le32_to_cpu(sect->type) & SEC_TYPE_SUBSYS_MASK)
+	    != SEC_TYPE_SUBSYS_CBMCU) ||
+	    ((le32_to_cpu(sect->type) & SEC_TYPE_SUBSYS_SEC_MASK)
+	    != SEC_TYPE_SUBSYS_SEC_IMG_SIGN)) {
+		dev_err(dev->dev, "Invalid CBMCU firmware\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* download global desc + sect map + cert section */
+	len = sizeof(struct mt76_connac3_multi_header_v2_raw_format) -
+	      offsetof(struct mt76_connac3_multi_header_v2_raw_format,
+		       global_desc_head) +
+	      sizeof(struct mt76_connac3_multi_header_v2_sec_raw_format) *
+	      le32_to_cpu(hdr->sec_num) +
+	      le32_to_cpu(hdr->sects[0].size);
+	dl = &hdr->global_desc_head[0];
+
+	ret = mt76_connac_cb_mcu_init_download(dev, len);
+	if (ret) {
+		dev_err(dev->dev, "Download cb cert section request failed\n");
+		goto out;
+	}
+
+	ret = __mt76_mcu_send_firmware(dev, MCU_CMD(FW_SCATTER),
+				       dl, len, max_len);
+	if (ret) {
+		dev_err(dev->dev, "Failed to send cb patch cert section\n");
+		goto out;
+	}
+
+	ret = mt76_connac_cb_mcu_start_patch(dev);
+	if (ret) {
+		dev_err(dev->dev, "CBMCU cert check fail\n");
+		goto out;
+	}
+
+	/* download cbmcu idlm */
+	for (i = 1; i < le32_to_cpu(hdr->sec_num); i++) {
+		dl = (uint8_t *)hdr + le32_to_cpu(hdr->sects[i].offset);
+		len = le32_to_cpu(hdr->sects[i].size);
+
+		ret = mt76_connac_cb_mcu_init_download(dev, len);
+		if (ret) {
+			dev_err(dev->dev,
+				"Download cb section %u request failed\n", i);
+			goto out;
+		}
+
+		ret = __mt76_mcu_send_firmware(dev, MCU_CMD(FW_SCATTER),
+					       dl, len, max_len);
+		if (ret) {
+			dev_err(dev->dev,
+				"Failed to send cb patch section %u\n", i);
+			goto out;
+		}
+	}
+
+	ret = mt76_connac_cb_mcu_start_patch(dev);
+	if (ret)
+		dev_err(dev->dev, "Failed to start cb patch\n");
+
+out:
+	sem = mt76_connac_cb_mcu_patch_sem_ctrl(dev, false);
+	switch (sem) {
+	case CB_PATCH_REL_SEM_SUCCESS:
+		break;
+	default:
+		ret = -EAGAIN;
+		dev_err(dev->dev, "Failed to release cb patch semaphore\n");
+		break;
+	}
+
+	release_firmware(fw);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mt76_connac3_load_cb_patch);
+
 int mt76_connac2_mcu_fill_message(struct mt76_dev *dev, struct sk_buff *skb,
 				  int cmd, int *wait_seq)
 {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index 6d0429f40b0f..5674090961d4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -35,6 +35,12 @@
 #define PATCH_SEC_ENC_SCRAMBLE_INFO_MASK	GENMASK(15, 0)
 #define PATCH_SEC_ENC_AES_KEY_MASK		GENMASK(7, 0)
 
+#define SEC_TYPE_SUBSYS_MASK			GENMASK(23, 16)
+#define SEC_TYPE_SUBSYS_CBMCU			BIT(16)
+
+#define SEC_TYPE_SUBSYS_SEC_MASK		GENMASK(15, 0)
+#define SEC_TYPE_SUBSYS_SEC_IMG_SIGN		0x05
+
 enum {
 	FW_TYPE_DEFAULT = 0,
 	FW_TYPE_CLC = 2,
@@ -193,6 +199,25 @@ struct mt76_connac2_fw_region {
 	u8 rsv1[14];
 } __packed;
 
+struct mt76_connac3_multi_header_v2_sec_raw_format {
+	__le32 type;
+	__le32 offset;
+	__le32 size;
+	u8 spec[52];
+} __packed;
+
+struct mt76_connac3_multi_header_v2_raw_format {
+	u8 pack_time[20];
+	u8 chip_id_eco_ver[8];
+	__le32 patch_ver;
+	u8 global_desc_head[4];
+	__le32 global_subsys;
+	u8 rsv2[4];
+	__le32 sec_num;
+	u8 rsv3[48];
+	struct mt76_connac3_multi_header_v2_sec_raw_format sects[];
+} __packed;
+
 struct tlv {
 	__le16 tag;
 	__le16 len;
@@ -1104,6 +1129,13 @@ enum {
 	PATCH_REL_SEM_SUCCESS
 };
 
+enum {
+	CB_PATCH_GET_SEM_NEED_PATCH,
+	CB_PATCH_IS_DL,
+	CB_PATCH_NO_SEM_NEED_PATCH,
+	CB_PATCH_REL_SEM_SUCCESS
+};
+
 enum {
 	FW_STATE_INITIAL,
 	FW_STATE_FW_DOWNLOAD,
@@ -1332,6 +1364,9 @@ enum {
 	MCU_CMD_PATCH_START_REQ = 0x05,
 	MCU_CMD_PATCH_FINISH_REQ = 0x07,
 	MCU_CMD_PATCH_SEM_CONTROL = 0x10,
+	MCU_CMD_CB_PATCH_SEM_CONTROL = 0x30,
+	MCU_CMD_CB_PATCH_START_REQ = 0x31,
+	MCU_CMD_CB_PATCH_FINISH_REQ = 0x32,
 	MCU_CMD_WA_PARAM = 0xc4,
 	MCU_CMD_EXT_CID = 0xed,
 	MCU_CMD_FW_SCATTER = 0xee,
@@ -2018,6 +2053,9 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
 				  u32 mode);
 int mt76_connac_mcu_start_patch(struct mt76_dev *dev);
 int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get);
+int mt76_connac_cb_mcu_init_download(struct mt76_dev *dev, u32 len);
+int mt76_connac_cb_mcu_start_patch(struct mt76_dev *dev);
+int mt76_connac_cb_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get);
 int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option);
 
 void mt76_connac_mcu_build_rnr_scan_param(struct mt76_dev *mdev,
@@ -2101,7 +2139,9 @@ int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index,
 int mt76_connac_mcu_sta_wed_update(struct mt76_dev *dev, struct sk_buff *skb);
 int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
 			  const char *fw_wa);
+int mt76_connac3_load_phy_ram(struct mt76_dev *dev, const char *fw_name);
 int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name);
+int mt76_connac3_load_cb_patch(struct mt76_dev *dev, const char *fw_name);
 int mt76_connac2_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb,
 				  int cmd, int *wait_seq);
 #endif /* __MT76_CONNAC_MCU_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index e94fa544ff20..0b4ca5cf5734 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -26,13 +26,24 @@ int mt7925_mcu_parse_response(struct mt76_dev *mdev, int cmd,
 	}
 
 	rxd = (struct mt7925_mcu_rxd *)skb->data;
-	if (seq != rxd->seq)
-		return -EAGAIN;
+	if (seq != rxd->seq) {
+		if (!is_mt7928(mdev))
+			return -EAGAIN;
+		else if (is_mt7928(mdev) &&
+			 cmd != MCU_CMD(CB_PATCH_SEM_CONTROL) &&
+			 cmd != MCU_CMD(CB_PATCH_FINISH_REQ))
+			return -EAGAIN;
+	}
 
 	if (cmd == MCU_CMD(PATCH_SEM_CONTROL) ||
 	    cmd == MCU_CMD(PATCH_FINISH_REQ)) {
 		skb_pull(skb, sizeof(*rxd) - 4);
 		ret = *skb->data;
+	} else if (is_mt7928(mdev) &&
+		   (cmd == MCU_CMD(CB_PATCH_SEM_CONTROL) ||
+		   cmd == MCU_CMD(CB_PATCH_FINISH_REQ))) {
+		skb_pull(skb, sizeof(*rxd) - 4);
+		ret = *skb->data;
 	} else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) ||
 		   cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) ||
 		   cmd == MCU_UNI_CMD(STA_REC_UPDATE) ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h
index 7d014de030c4..8c7ecd3ce126 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x.h
@@ -47,6 +47,7 @@
 #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 MT7928_FIRMWARE_WM	"mediatek/mt7928/WIFI_RAM_CODE_MT7935_1_1.bin"
 
 #define MT7902_ROM_PATCH	"mediatek/WIFI_MT7902_patch_mcu_1_1_hdr.bin"
 #define MT7920_ROM_PATCH	"mediatek/WIFI_MT7961_patch_mcu_1a_2_hdr.bin"
@@ -54,6 +55,10 @@
 #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 MT7928_ROM_PATCH	"mediatek/mt7928/WIFI_MT7935_PATCH_MCU_1_1_hdr.bin"
+
+#define MT7928_CB_ROM_PATCH	"mediatek/mt7928/CBMCU_CODE_MT7935_1_1.bin"
+#define MT7928_PHY_RAM		"mediatek/mt7928/WIFI_MT7935_PHY_RAM_CODE_1_1.bin"
 
 #define MT792x_SDIO_HDR_TX_BYTES	GENMASK(15, 0)
 #define MT792x_SDIO_HDR_PKT_TYPE	GENMASK(17, 16)
@@ -494,6 +499,8 @@ static inline char *mt792x_ram_name(struct mt792x_dev *dev)
 		return MT7925_FIRMWARE_WM;
 	case 0x7927:
 		return MT7927_FIRMWARE_WM;
+	case 0x7928:
+		return MT7928_FIRMWARE_WM;
 	default:
 		return MT7921_FIRMWARE_WM;
 	}
@@ -512,11 +519,33 @@ static inline char *mt792x_patch_name(struct mt792x_dev *dev)
 		return MT7925_ROM_PATCH;
 	case 0x7927:
 		return MT7927_ROM_PATCH;
+	case 0x7928:
+		return MT7928_ROM_PATCH;
 	default:
 		return MT7921_ROM_PATCH;
 	}
 }
 
+static inline char *mt792x_cb_patch_name(struct mt792x_dev *dev)
+{
+	switch (mt76_chip(&dev->mt76)) {
+	case 0x7928:
+		return MT7928_CB_ROM_PATCH;
+	default:
+		return NULL;
+	}
+}
+
+static inline char *mt792x_phy_ram_name(struct mt792x_dev *dev)
+{
+	switch (mt76_chip(&dev->mt76)) {
+	case 0x7928:
+		return MT7928_PHY_RAM;
+	default:
+		return NULL;
+	}
+}
+
 int mt792x_load_firmware(struct mt792x_dev *dev);
 
 /* usb */
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
index b50825eccdaf..9bd679b7e889 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
@@ -985,6 +985,15 @@ int mt792x_load_firmware(struct mt792x_dev *dev)
 		dev_warn(dev->mt76.dev,
 			 "MCU is not ready for firmware download\n");
 
+	if (is_mt7928(&dev->mt76)) {
+		dev_info(dev->mt76.dev, "Loading CB firmware patch: %s\n",
+			 mt792x_cb_patch_name(dev));
+		ret = mt76_connac3_load_cb_patch(&dev->mt76, mt792x_cb_patch_name(dev));
+		if (ret)
+			return ret;
+	}
+
+	dev_info(dev->mt76.dev, "Loading firmware patch: %s\n", mt792x_patch_name(dev));
 	ret = mt76_connac2_load_patch(&dev->mt76, mt792x_patch_name(dev));
 	if (ret)
 		return ret;
@@ -996,6 +1005,12 @@ int mt792x_load_firmware(struct mt792x_dev *dev)
 			ret = __mt792x_mcu_drv_pmctrl(dev);
 	}
 
+	if (is_mt7928(&dev->mt76)) {
+		ret = mt76_connac3_load_phy_ram(&dev->mt76, mt792x_phy_ram_name(dev));
+		if (ret)
+			return ret;
+	}
+
 	ret = mt76_connac2_load_ram(&dev->mt76, mt792x_ram_name(dev), NULL);
 	if (ret)
 		return ret;
-- 
2.45.2




More information about the Linux-mediatek mailing list