From 03135a5a6ed37329ea8d0add992ab15555dc612d Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 20 Jan 2026 11:17:17 +0100 Subject: [PATCH 1/2] dt-bindings: net: airoha: npu: Add firmware-name property Add firmware-name property in order to introduce the capability to specify the firmware names used for 'RiscV core' and 'Data section' binaries. This patch is needed because NPU firmware binaries are board specific since they depend on the MediaTek WiFi chip used on the board (e.g. MT7996 or MT7992) and the WiFi chip version info is not available in the NPU driver. This is a preliminary patch to enable MT76 NPU offloading if the Airoha SoC is equipped with MT7996 (Eagle) WiFi chipset. Reviewed-by: Andrew Lunn Reviewed-by: Krzysztof Kozlowski Signed-off-by: Lorenzo Bianconi Link: https://patch.msgid.link/20260120-airoha-npu-firmware-name-v4-1-88999628b4c1@kernel.org Signed-off-by: Jakub Kicinski --- .../devicetree/bindings/net/airoha,en7581-npu.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/net/airoha,en7581-npu.yaml b/Documentation/devicetree/bindings/net/airoha,en7581-npu.yaml index 19860b41286f..aefa19c5b424 100644 --- a/Documentation/devicetree/bindings/net/airoha,en7581-npu.yaml +++ b/Documentation/devicetree/bindings/net/airoha,en7581-npu.yaml @@ -59,6 +59,11 @@ properties: - const: ba minItems: 1 + firmware-name: + items: + - description: Firmware name of RiscV core + - description: Firmware name of Data section + required: - compatible - reg @@ -96,5 +101,7 @@ examples: memory-region = <&npu_firmware>, <&npu_pkt>, <&npu_txpkt>, <&npu_txbufid>, <&npu_ba>; memory-region-names = "firmware", "pkt", "tx-pkt", "tx-bufid", "ba"; + firmware-name = "airoha/en7581_npu_rv32.bin", + "airoha/en7581_npu_data.bin"; }; }; From 3847173525e307ebcd23bd4863da943ea78b0057 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 20 Jan 2026 11:17:18 +0100 Subject: [PATCH 2/2] net: airoha: npu: Add the capability to read firmware names from dts Introduce the capability to read the firmware binary names from device-tree using the firmware-name property if available. This patch is needed because NPU firmware binaries are board specific since they depend on the MediaTek WiFi chip used on the board (e.g. MT7996 or MT7992) and the WiFi chip version info is not available in the NPU driver. This is a preliminary patch to enable MT76 NPU offloading if the Airoha SoC is equipped with MT7996 (Eagle) WiFi chipset. Signed-off-by: Lorenzo Bianconi Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20260120-airoha-npu-firmware-name-v4-2-88999628b4c1@kernel.org Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/airoha/airoha_npu.c | 46 ++++++++++++++++++++---- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c index a56b3780bb62..89f22f3f47dc 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.c +++ b/drivers/net/ethernet/airoha/airoha_npu.c @@ -16,6 +16,8 @@ #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" +#define NPU_EN7581_7996_FIRMWARE_DATA "airoha/en7581_MT7996_npu_data.bin" +#define NPU_EN7581_7996_FIRMWARE_RV32 "airoha/en7581_MT7996_npu_rv32.bin" #define NPU_AN7583_FIRMWARE_DATA "airoha/an7583_npu_data.bin" #define NPU_AN7583_FIRMWARE_RV32 "airoha/an7583_npu_rv32.bin" #define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000 @@ -195,18 +197,18 @@ static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id, } static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr, - const struct airoha_npu_fw *fw_info) + const char *fw_name, int fw_max_size) { const struct firmware *fw; int ret; - ret = request_firmware(&fw, fw_info->name, dev); + ret = request_firmware(&fw, fw_name, dev); if (ret) return ret == -ENOENT ? -EPROBE_DEFER : ret; - if (fw->size > fw_info->max_size) { + if (fw->size > fw_max_size) { dev_err(dev, "%s: fw size too overlimit (%zu)\n", - fw_info->name, fw->size); + fw_name, fw->size); ret = -E2BIG; goto out; } @@ -218,6 +220,28 @@ static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr, return ret; } +static int +airoha_npu_load_firmware_from_dts(struct device *dev, void __iomem *addr, + void __iomem *base) +{ + const char *fw_names[2]; + int ret; + + ret = of_property_read_string_array(dev->of_node, "firmware-name", + fw_names, ARRAY_SIZE(fw_names)); + if (ret != ARRAY_SIZE(fw_names)) + return -EINVAL; + + ret = airoha_npu_load_firmware(dev, addr, fw_names[0], + NPU_EN7581_FIRMWARE_RV32_MAX_SIZE); + if (ret) + return ret; + + return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM, + fw_names[1], + NPU_EN7581_FIRMWARE_DATA_MAX_SIZE); +} + static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, struct resource *res) { @@ -233,14 +257,22 @@ static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, if (IS_ERR(addr)) return PTR_ERR(addr); + /* Try to load firmware images using the firmware names provided via + * dts if available. + */ + if (of_find_property(dev->of_node, "firmware-name", NULL)) + return airoha_npu_load_firmware_from_dts(dev, addr, base); + /* Load rv32 npu firmware */ - ret = airoha_npu_load_firmware(dev, addr, &soc->fw_rv32); + ret = airoha_npu_load_firmware(dev, addr, soc->fw_rv32.name, + soc->fw_rv32.max_size); if (ret) return ret; /* Load data npu firmware */ return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM, - &soc->fw_data); + soc->fw_data.name, + soc->fw_data.max_size); } static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) @@ -790,6 +822,8 @@ module_platform_driver(airoha_npu_driver); MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); +MODULE_FIRMWARE(NPU_EN7581_7996_FIRMWARE_DATA); +MODULE_FIRMWARE(NPU_EN7581_7996_FIRMWARE_RV32); MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_DATA); MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_RV32); MODULE_LICENSE("GPL");