]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
net: phy: aquantia: use generic firmware loader
authorBeiyan Yun <root@infi.wang>
Sat, 1 Nov 2025 12:31:35 +0000 (20:31 +0800)
committerJerome Forissier <jerome.forissier@linaro.org>
Mon, 1 Dec 2025 09:37:06 +0000 (10:37 +0100)
Aquantia PHYs are being used w/o SPI flash in some routers recently.
Current firmware loader only attempts to load from FS on top of MMC,
limiting the use on many devices.

Removed the old firmware loader, migrate to generic script based firmware
loader to allow a wider range and runtime override of firmware source.
(e.g., MMC, USB, UBIFS).

Tested on Buffalo WXR18000BE10P with UBIFS.

Signed-off-by: Beiyan Yun <root@infi.wang>
drivers/net/phy/Kconfig
drivers/net/phy/aquantia.c

index 57803ab5c59c6e39269293ca76557e6979f2727a..d0aab0b8fe879aae5d5397210244b53e6c42ff24 100644 (file)
@@ -91,23 +91,22 @@ menuconfig PHY_AQUANTIA
 config PHY_AQUANTIA_UPLOAD_FW
        bool "Aquantia firmware loading support"
        depends on PHY_AQUANTIA
+       select FW_LOADER
        help
-               Aquantia PHYs use firmware which can be either loaded automatically
-               from storage directly attached to the phy or loaded by the boot loader
-               via MDIO commands.  The firmware is loaded from a file, specified by
-               the PHY_AQUANTIA_FW_PART and PHY_AQUANTIA_FW_NAME options.
+         Aquantia PHYs use firmware which can be either loaded automatically
+         from storage directly attached to the phy or loaded by the boot loader
+         via MDIO commands.
 
-config PHY_AQUANTIA_FW_PART
-       string "Aquantia firmware partition"
-       depends on PHY_AQUANTIA_UPLOAD_FW
-       help
-               Partition containing the firmware file.
+         This option enables loading the firmware using the generic
+         firmware loader framework.
 
-config PHY_AQUANTIA_FW_NAME
-       string "Aquantia firmware filename"
+config PHY_AQUANTIA_FW_MAX_SIZE
+       hex "Max firmware size"
        depends on PHY_AQUANTIA_UPLOAD_FW
+       default 0x80000
        help
-               Firmware filename.
+         The maximum size of the Aquantia PHY firmware. This is used to
+         allocate a buffer to load the firmware into.
 
 config PHY_ATHEROS
        bool "Atheros Ethernet PHYs support"
index fc2476fb0387dae57700521497b49b271cdc6a58..e0deef58f52497b10c1babe30603686e07f0687a 100644 (file)
@@ -16,7 +16,9 @@
 #include <u-boot/crc.h>
 #include <malloc.h>
 #include <asm/byteorder.h>
-#include <fs.h>
+#if (IS_ENABLED(CONFIG_PHY_AQUANTIA_UPLOAD_FW))
+#include <fw_loader.h>
+#endif
 
 #define AQUNTIA_10G_CTL                0x20
 #define AQUNTIA_VENDOR_P1      0xc400
@@ -127,52 +129,29 @@ struct fw_header {
 
 #pragma pack()
 
-#if defined(CONFIG_PHY_AQUANTIA_UPLOAD_FW)
-static int aquantia_read_fw(u8 **fw_addr, size_t *fw_length)
+#if (IS_ENABLED(CONFIG_PHY_AQUANTIA_UPLOAD_FW))
+int __weak aquantia_read_fw(struct phy_device *phydev,
+                           u8 **fw_addr, size_t *fw_length)
 {
-       loff_t length, read;
        int ret;
-       void *addr = NULL;
-
-       *fw_addr = NULL;
-       *fw_length = 0;
-       debug("Loading Aquantia microcode from %s %s\n",
-             CONFIG_PHY_AQUANTIA_FW_PART, CONFIG_PHY_AQUANTIA_FW_NAME);
-       ret = fs_set_blk_dev("mmc", CONFIG_PHY_AQUANTIA_FW_PART, FS_TYPE_ANY);
-       if (ret < 0)
-               goto cleanup;
-
-       ret = fs_size(CONFIG_PHY_AQUANTIA_FW_NAME, &length);
-       if (ret < 0)
-               goto cleanup;
-
-       addr = malloc(length);
-       if (!addr) {
-               ret = -ENOMEM;
-               goto cleanup;
-       }
-
-       ret = fs_set_blk_dev("mmc", CONFIG_PHY_AQUANTIA_FW_PART, FS_TYPE_ANY);
-       if (ret < 0)
-               goto cleanup;
-
-       ret = fs_read(CONFIG_PHY_AQUANTIA_FW_NAME, (ulong)addr, 0, length,
-                     &read);
-       if (ret < 0)
-               goto cleanup;
+       u8 *microcode;
 
-       *fw_addr = addr;
-       *fw_length = length;
-       debug("Found Aquantia microcode.\n");
+       microcode = malloc(CONFIG_PHY_AQUANTIA_FW_MAX_SIZE);
+       if (!microcode) {
+               printf("Failed to allocate memory for firmware\n");
+               return -ENOMEM;
+       }
 
-cleanup:
-       if (ret < 0) {
-               printf("loading firmware file %s %s failed with error %d\n",
-                      CONFIG_PHY_AQUANTIA_FW_PART,
-                      CONFIG_PHY_AQUANTIA_FW_NAME, ret);
-               free(addr);
+       ret = request_firmware_into_buf_via_script(
+               microcode, CONFIG_PHY_AQUANTIA_FW_MAX_SIZE,
+               "aqr_phy_load_firmware", fw_length);
+       if (ret) {
+               free(microcode);
+               return ret;
        }
-       return ret;
+
+       *fw_addr = microcode;
+       return 1;
 }
 
 /* load data into the phy's memory */
@@ -293,16 +272,17 @@ static int aquantia_do_upload_firmware(struct phy_device *phydev,
 
 static int aquantia_upload_firmware(struct phy_device *phydev)
 {
-       int ret;
+       int ret, fwrc;
        u8 *addr = NULL;
-       size_t fw_length = 0;
+       size_t fw_length;
 
-       ret = aquantia_read_fw(&addr, &fw_length);
-       if (ret != 0)
-               return ret;
+       fwrc = aquantia_read_fw(phydev, &addr, &fw_length);
+       if (fwrc < 0)
+               return fwrc;
 
        ret = aquantia_do_upload_firmware(phydev, addr, fw_length);
-       free(addr);
+       if (fwrc > 0)
+               free(addr);
 
        return ret;
 }