diff --git a/target/linux/airoha/patches-6.18/181-v7.3-net-airoha-npu-load-the-firmware-without-the-sysfs-fall.patch b/target/linux/airoha/patches-6.18/181-v7.3-net-airoha-npu-load-the-firmware-without-the-sysfs-fall.patch new file mode 100644 index 00000000000..3313b405694 --- /dev/null +++ b/target/linux/airoha/patches-6.18/181-v7.3-net-airoha-npu-load-the-firmware-without-the-sysfs-fall.patch @@ -0,0 +1,104 @@ +From a085e68b13906a6a4d8b16e3b763e13f05904cc8 Mon Sep 17 00:00:00 2001 +From: Vitaliy Sochnev +Date: Tue, 11 Aug 2026 19:16:59 +0100 +Subject: [PATCH] net: airoha: npu: load the firmware without the sysfs + fallback + +airoha_npu_load_firmware() maps a missing firmware file to -EPROBE_DEFER +so that the NPU can be brought up once the rootfs carrying /lib/firmware +has been mounted. That mapping holds only as long as request_firmware() +reports -ENOENT. + +It does not when the sysfs fallback is in play. With +CONFIG_FW_LOADER_USER_HELPER_FALLBACK set, or with the fallback armed at +runtime through /proc/sys/kernel/firmware_config/force_sysfs_fallback, +request_firmware() hands the request to a userspace helper, waits out the +full loading_timeout and returns -ETIMEDOUT. The -ENOENT test no longer +matches, dev_err_probe() turns the result into a hard failure, and the +NPU is left unbound after stalling the boot for 60 seconds: + + airoha-npu 1e900000.npu: Direct firmware load for airoha/en7581_npu_rv32.bin failed with error -2 + airoha-npu 1e900000.npu: Falling back to sysfs fallback for: airoha/en7581_npu_rv32.bin + airoha-npu 1e900000.npu: error -ETIMEDOUT: failed to run npu firmware + airoha-npu 1e900000.npu: probe with driver airoha-npu failed with error -110 + +Clearing FW_LOADER_USER_HELPER in the configuration is not a dependable +guard against this, because unrelated drivers select it. On the affected +build the symbol was turned back on by LEDS_LP55XX_COMMON, even though +the platform had explicitly disabled it. + +Use request_firmware_direct() instead. It sets FW_OPT_NOFALLBACK_SYSFS, +so a missing file is reported as -ENOENT whatever the firmware loader is +configured to do, and the deferred probe path works as intended. + +Two consequences are worth stating plainly. + +The helper is not merely bypassed for the boot-before-rootfs case. +fw_run_sysfs_fallback() returns early on FW_OPT_NOFALLBACK_SYSFS, so this +driver's firmware requests can no longer be served by a usermode helper +at all, including on a system where that is the only delivery route; +having no second firmware source, the driver would defer forever there. +That is a deliberate trade-off: the -ENOENT to -EPROBE_DEFER mapping was +written to wait for a filesystem, and the sysfs helper interface has had +no in-tree consumer since udev dropped firmware loading. + +request_firmware_direct() also sets FW_OPT_NO_WARN, which drops the only +message naming the file that failed to load. Report it from the driver +instead, so the name lands in the deferred probe reason and shows up in +the "deferred probe pending" line emitted at +driver_deferred_probe_timeout. The generic report in airoha_npu_probe() +goes away with it, since it would otherwise overwrite that reason with a +message naming nothing; of the paths it covered, devm_ioremap_resource() +reports itself and the malformed firmware-name property now does too. + +Measured on a Nokia XG-040G-MD with FW_LOADER_USER_HELPER=y and +FW_LOADER_USER_HELPER_FALLBACK=y forced on, two images from the same +tree differing only by this patch: + + without: fallback at 2.477s -> -ETIMEDOUT at 64.555s -> probe failed + with -110, preinit at 69.6s, NPU unbound + with: no fallback, NPU fw version 1456.62 at 3.665s, preinit at + 7.6s + +Cc: stable+noautosel@kernel.org # never worked +Signed-off-by: Vitaliy Sochnev +Reviewed-by: Simon Horman +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_npu.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -202,9 +202,10 @@ static int airoha_npu_load_firmware(stru + const struct firmware *fw; + int ret; + +- ret = request_firmware(&fw, fw_name, dev); ++ ret = request_firmware_direct(&fw, fw_name, dev); + if (ret) +- return ret == -ENOENT ? -EPROBE_DEFER : ret; ++ return dev_err_probe(dev, ret == -ENOENT ? -EPROBE_DEFER : ret, ++ "failed to load %s\n", fw_name); + + if (fw->size > fw_max_size) { + dev_err(dev, "%s: fw size too overlimit (%zu)\n", +@@ -230,7 +231,8 @@ airoha_npu_load_firmware_from_dts(struct + 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; ++ return dev_err_probe(dev, -EINVAL, ++ "invalid firmware-name property\n"); + + ret = airoha_npu_load_firmware(dev, addr, fw_names[0], + NPU_EN7581_FIRMWARE_RV32_MAX_SIZE); +@@ -772,7 +774,7 @@ static int airoha_npu_probe(struct platf + + err = airoha_npu_run_firmware(dev, base, &res); + if (err) +- return dev_err_probe(dev, err, "failed to run npu firmware\n"); ++ return err; + + regmap_write(npu->regmap, REG_CR_NPU_MIB(10), + res.start + NPU_EN7581_FIRMWARE_RV32_MAX_SIZE); diff --git a/target/linux/airoha/patches-6.18/921-net-airoha-npu-load-firmware-without-the-sysfs-fallb.patch b/target/linux/airoha/patches-6.18/921-net-airoha-npu-load-firmware-without-the-sysfs-fallb.patch deleted file mode 100644 index a07845abbf9..00000000000 --- a/target/linux/airoha/patches-6.18/921-net-airoha-npu-load-firmware-without-the-sysfs-fallb.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0509cfb2607a5a084617701f969b4bad0fd0f157 Mon Sep 17 00:00:00 2001 -From: Vitaliy Sochnev -Date: Fri, 7 Aug 2026 03:37:00 +0100 -Subject: [PATCH] net: airoha: npu: load the firmware without the sysfs - fallback - -airoha_npu_load_firmware() maps a missing firmware file to -EPROBE_DEFER -so that the NPU can be brought up once the rootfs carrying /lib/firmware -has been mounted. That mapping holds only as long as request_firmware() -reports -ENOENT. - -It does not when the sysfs fallback is in play. With -CONFIG_FW_LOADER_USER_HELPER_FALLBACK set, or with the fallback armed at -runtime through /proc/sys/kernel/firmware_config/force_sysfs_fallback, -request_firmware() hands the request to a userspace helper, waits out the -full loading_timeout and returns -ETIMEDOUT. The -ENOENT test no longer -matches, dev_err_probe() turns the result into a hard failure, and the -NPU is left unbound after stalling the boot for 60 seconds: - - airoha-npu 1e900000.npu: Direct firmware load for airoha/en7581_npu_rv32.bin failed with error -2 - airoha-npu 1e900000.npu: Falling back to sysfs fallback for: airoha/en7581_npu_rv32.bin - airoha-npu 1e900000.npu: error -ETIMEDOUT: failed to run npu firmware - airoha-npu 1e900000.npu: probe with driver airoha-npu failed with error -110 - -Clearing FW_LOADER_USER_HELPER in the configuration is not a dependable -guard against this, because unrelated drivers select it. On the affected -build the symbol was turned back on by LEDS_LP55XX_COMMON, even though -the platform had explicitly disabled it. - -request_firmware_direct() sets FW_OPT_NOFALLBACK_SYSFS, so a missing file -is reported as -ENOENT whatever the firmware loader is configured to do, -and the deferred probe path works as it was meant to. - -Measured on a Nokia XG-040G-MD with FW_LOADER_USER_HELPER=y and -FW_LOADER_USER_HELPER_FALLBACK=y, on two images from the same tree -differing only by this patch: without it the probe fails with --ETIMEDOUT after 64.5s and the NPU stays unbound, with it the NPU -reports its firmware version at 3.7s. The fallback is compiled in and -forced in both cases; the patch does not disable it, it only keeps the -driver from falling into it. - -Fixes: 23290c7bc190 ("net: airoha: Introduce Airoha NPU support") -Cc: stable@vger.kernel.org -Signed-off-by: Vitaliy Sochnev ---- - drivers/net/ethernet/airoha/airoha_npu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -202,7 +202,7 @@ static int airoha_npu_load_firmware(stru - const struct firmware *fw; - int ret; - -- ret = request_firmware(&fw, fw_name, dev); -+ ret = request_firmware_direct(&fw, fw_name, dev); - if (ret) - return ret == -ENOENT ? -EPROBE_DEFER : ret; - diff --git a/target/linux/airoha/patches-6.18/924-net-airoha-npu-use-coherent-mailbox-dma.patch b/target/linux/airoha/patches-6.18/924-net-airoha-npu-use-coherent-mailbox-dma.patch index a137d16c449..1cec50f4619 100644 --- a/target/linux/airoha/patches-6.18/924-net-airoha-npu-use-coherent-mailbox-dma.patch +++ b/target/linux/airoha/patches-6.18/924-net-airoha-npu-use-coherent-mailbox-dma.patch @@ -119,7 +119,7 @@ Signed-off-by: Daniel Pawlik static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr, const char *fw_name, int fw_max_size) { -@@ -497,9 +522,8 @@ static int airoha_npu_wlan_msg_get(struc +@@ -499,9 +524,8 @@ static int airoha_npu_wlan_msg_get(struc wlan_data->func_type = NPU_OP_GET; wlan_data->func_id = func_id; @@ -131,7 +131,7 @@ Signed-off-by: Daniel Pawlik kfree(wlan_data); return err; -@@ -770,6 +794,15 @@ static int airoha_npu_probe(struct platf +@@ -772,6 +796,15 @@ static int airoha_npu_probe(struct platf if (err) return err; @@ -146,7 +146,7 @@ Signed-off-by: Daniel Pawlik + err = airoha_npu_run_firmware(dev, base, &res); if (err) - return dev_err_probe(dev, err, "failed to run npu firmware\n"); + return err; --- a/include/linux/soc/airoha/airoha_offload.h +++ b/include/linux/soc/airoha/airoha_offload.h @@ -173,6 +173,9 @@ struct airoha_npu {