* [PATCH v4 0/5] net: phy: aquantia: Switch to generic firmware loader
@ 2025-10-31 15:21 Beiyan Yun
2025-10-31 15:21 ` [PATCH v4 1/5] net: phy: aquantia: refresh format Beiyan Yun
` (4 more replies)
0 siblings, 5 replies; 22+ messages in thread
From: Beiyan Yun @ 2025-10-31 15:21 UTC (permalink / raw)
To: u-boot
Cc: Yao Zi, Marek Vasut, Tom Rini, Beiyan Yun, Jerome Forissier,
Joe Hershberger, Lucien.Jheng, Ramon Fried, Romain Gantois,
Siddharth Vadapalli, Weijie Gao
Hi,
This patch series refactors the Aquantia PHY firmware loader to use
the generic fsloader framework.
The existing loader is limited to loading firmware from an MMC device,
which restricts its use on many devices (e.g., routers) that may use
other storage like USB or have a UBIFS root filesystem. Migrating to the
generic firmware loader allows firmware to be sourced from any backend
supported by the fwloader and fsloader framework.
The series is structured as follows:
- The first patch is formatting.
- The second patch aligns binding document with upstream and prepares
for the migration.
- The third patch aligns binding for MDI with upstream.
- The fourth patch prepares current loading code for fsloader.
- The final and main patch replaces the custom loader with generic one.
Kept smb-addr intact as NXP is the only consumer.
This change has been tested on a Buffalo WXR18000BE10P router, loading
firmware from a UBIFS volume for Marvell CUX3410.
Changes in v4:
- net: phy: aquantia: refresh format
- net: phy: aquantia: refactor firmware upload helpers
- Split firmware upload helpers change
- Reorder `aquantia_read_fw`
- Make `aquantia_read_fw` weak to allow overide
- Rename exit label in `aquantia_read_fw`
- Kconfig polish
Changes in v3:
- Select FW_LOADER with PHY_AQUANTIA_UPLOAD_FW
Changes in v2:
- doc: bindings: use upstream bindings for aquantia phy
- net: phy: aquantia: replace the "mdi-reversal" node with "marvell,mdi-cfg-order"
- Add support for script based loader
Beiyan Yun (5):
net: phy: aquantia: refresh format
doc: bindings: use upstream bindings for aquantia phy
net: phy: aquantia: replace the "mdi-reversal" node with
"marvell,mdi-cfg-order"
net: phy: aquantia: refactor firmware upload helpers
net: phy: aquantia: use generic firmware loader
arch/arm/dts/fsl-sch-30841.dtsi | 8 +-
arch/arm/dts/fsl-sch-30842.dtsi | 2 +-
doc/device-tree-bindings/net/aquantia-phy.txt | 15 +-
drivers/net/phy/Kconfig | 28 +-
drivers/net/phy/aquantia.c | 299 ++++++++++--------
5 files changed, 188 insertions(+), 164 deletions(-)
--
2.47.3
base-commit: 08bf42e1faa4411cd347c2e370da790a0116e318
branch: aquantia-fsloader-v4
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v4 1/5] net: phy: aquantia: refresh format
2025-10-31 15:21 [PATCH v4 0/5] net: phy: aquantia: Switch to generic firmware loader Beiyan Yun
@ 2025-10-31 15:21 ` Beiyan Yun
2025-10-31 15:51 ` Marek Vasut
2025-10-31 15:21 ` [PATCH v4 2/5] doc: bindings: use upstream bindings for aquantia phy Beiyan Yun
` (3 subsequent siblings)
4 siblings, 1 reply; 22+ messages in thread
From: Beiyan Yun @ 2025-10-31 15:21 UTC (permalink / raw)
To: u-boot
Cc: Yao Zi, Marek Vasut, Tom Rini, Beiyan Yun, Jerome Forissier,
Joe Hershberger, Ramon Fried, Siddharth Vadapalli
Refresh format using clang-format.
Signed-off-by: Beiyan Yun <root@infi.wang>
---
Changes in v4:
- New
drivers/net/phy/aquantia.c | 159 +++++++++++++++++--------------------
1 file changed, 75 insertions(+), 84 deletions(-)
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 903fcd667f6..439c4c48bdc 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -18,28 +18,28 @@
#include <asm/byteorder.h>
#include <fs.h>
-#define AQUNTIA_10G_CTL 0x20
-#define AQUNTIA_VENDOR_P1 0xc400
+#define AQUNTIA_10G_CTL 0x20
+#define AQUNTIA_VENDOR_P1 0xc400
-#define AQUNTIA_SPEED_LSB_MASK 0x2000
-#define AQUNTIA_SPEED_MSB_MASK 0x40
+#define AQUNTIA_SPEED_LSB_MASK 0x2000
+#define AQUNTIA_SPEED_MSB_MASK 0x40
-#define AQUANTIA_SYSTEM_INTERFACE_SR 0xe812
-#define AQUANTIA_SYSTEM_INTERFACE_SR_READY BIT(0)
+#define AQUANTIA_SYSTEM_INTERFACE_SR 0xe812
+#define AQUANTIA_SYSTEM_INTERFACE_SR_READY BIT(0)
#define AQUANTIA_VENDOR_PROVISIONING_REG 0xC441
-#define AQUANTIA_FIRMWARE_ID 0x20
-#define AQUANTIA_RESERVED_STATUS 0xc885
-#define AQUANTIA_FIRMWARE_MAJOR_MASK 0xff00
-#define AQUANTIA_FIRMWARE_MINOR_MASK 0xff
-#define AQUANTIA_FIRMWARE_BUILD_MASK 0xf0
+#define AQUANTIA_FIRMWARE_ID 0x20
+#define AQUANTIA_RESERVED_STATUS 0xc885
+#define AQUANTIA_FIRMWARE_MAJOR_MASK 0xff00
+#define AQUANTIA_FIRMWARE_MINOR_MASK 0xff
+#define AQUANTIA_FIRMWARE_BUILD_MASK 0xf0
#define AQUANTIA_USX_AUTONEG_CONTROL_ENA 0x0008
-#define AQUANTIA_SI_IN_USE_MASK 0x0078
-#define AQUANTIA_SI_USXGMII 0x0018
+#define AQUANTIA_SI_IN_USE_MASK 0x0078
+#define AQUANTIA_SI_USXGMII 0x0018
/* registers in MDIO_MMD_VEND1 region */
-#define AQUANTIA_VND1_GLOBAL_SC 0x000
-#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb)
+#define AQUANTIA_VND1_GLOBAL_SC 0x000
+#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb)
#define GLOBAL_FIRMWARE_ID 0x20
#define GLOBAL_FAULT 0xc850
@@ -71,35 +71,35 @@
#define UP_RUN_STALL_OVERRIDE BIT(6)
#define UP_RUN_STALL BIT(0)
-#define AQUANTIA_PMA_RX_VENDOR_P1 0xe400
-#define AQUANTIA_PMA_RX_VENDOR_P1_MDI_MSK GENMASK(1, 0)
+#define AQUANTIA_PMA_RX_VENDOR_P1 0xe400
+#define AQUANTIA_PMA_RX_VENDOR_P1_MDI_MSK GENMASK(1, 0)
/* MDI reversal configured through registers */
-#define AQUANTIA_PMA_RX_VENDOR_P1_MDI_CFG BIT(1)
+#define AQUANTIA_PMA_RX_VENDOR_P1_MDI_CFG BIT(1)
/* MDI reversal enabled */
-#define AQUANTIA_PMA_RX_VENDOR_P1_MDI_REV BIT(0)
+#define AQUANTIA_PMA_RX_VENDOR_P1_MDI_REV BIT(0)
/*
* global start rate, the protocol associated with this speed is used by default
* on SI.
*/
-#define AQUANTIA_VND1_GSTART_RATE 0x31a
-#define AQUANTIA_VND1_GSTART_RATE_OFF 0
-#define AQUANTIA_VND1_GSTART_RATE_100M 1
-#define AQUANTIA_VND1_GSTART_RATE_1G 2
-#define AQUANTIA_VND1_GSTART_RATE_10G 3
-#define AQUANTIA_VND1_GSTART_RATE_2_5G 4
-#define AQUANTIA_VND1_GSTART_RATE_5G 5
+#define AQUANTIA_VND1_GSTART_RATE 0x31a
+#define AQUANTIA_VND1_GSTART_RATE_OFF 0
+#define AQUANTIA_VND1_GSTART_RATE_100M 1
+#define AQUANTIA_VND1_GSTART_RATE_1G 2
+#define AQUANTIA_VND1_GSTART_RATE_10G 3
+#define AQUANTIA_VND1_GSTART_RATE_2_5G 4
+#define AQUANTIA_VND1_GSTART_RATE_5G 5
/* SYSCFG registers for 100M, 1G, 2.5G, 5G, 10G */
-#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b
-#define AQUANTIA_VND1_GSYSCFG_100M 0
-#define AQUANTIA_VND1_GSYSCFG_1G 1
-#define AQUANTIA_VND1_GSYSCFG_2_5G 2
-#define AQUANTIA_VND1_GSYSCFG_5G 3
-#define AQUANTIA_VND1_GSYSCFG_10G 4
+#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b
+#define AQUANTIA_VND1_GSYSCFG_100M 0
+#define AQUANTIA_VND1_GSYSCFG_1G 1
+#define AQUANTIA_VND1_GSYSCFG_2_5G 2
+#define AQUANTIA_VND1_GSYSCFG_5G 3
+#define AQUANTIA_VND1_GSYSCFG_10G 4
-#define AQUANTIA_VND1_SMBUS0 0xc485
-#define AQUANTIA_VND1_SMBUS1 0xc495
+#define AQUANTIA_VND1_SMBUS0 0xc485
+#define AQUANTIA_VND1_SMBUS1 0xc495
/* addresses of memory segments in the phy */
#define DRAM_BASE_ADDR 0x3FFE0000
@@ -111,10 +111,10 @@
#define HEADER_OFFSET 0x300
/* driver private data */
-#define AQUANTIA_NA 0
-#define AQUANTIA_GEN1 1
-#define AQUANTIA_GEN2 2
-#define AQUANTIA_GEN3 3
+#define AQUANTIA_NA 0
+#define AQUANTIA_GEN1 1
+#define AQUANTIA_GEN2 2
+#define AQUANTIA_GEN3 3
#pragma pack(1)
struct fw_header {
@@ -168,8 +168,8 @@ static int aquantia_read_fw(u8 **fw_addr, size_t *fw_length)
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);
+ CONFIG_PHY_AQUANTIA_FW_PART, CONFIG_PHY_AQUANTIA_FW_NAME,
+ ret);
free(addr);
}
return ret;
@@ -232,7 +232,7 @@ static int aquantia_upload_firmware(struct phy_device *phydev)
if (ret != 0)
return ret;
- read_crc = (addr[fw_length - 2] << 8) | addr[fw_length - 1];
+ read_crc = (addr[fw_length - 2] << 8) | addr[fw_length - 1];
calculated_crc = crc16_ccitt(0, addr, fw_length - 2);
if (read_crc != calculated_crc) {
printf("%s bad firmware crc: file 0x%04x calculated 0x%04x\n",
@@ -257,21 +257,22 @@ static int aquantia_upload_firmware(struct phy_device *phydev)
strlcpy(version, (char *)&addr[dram_offset + VERSION_STRING_OFFSET],
VERSION_STRING_SIZE);
- printf("%s loading firmware version '%s'\n", phydev->dev->name, version);
+ printf("%s loading firmware version '%s'\n", phydev->dev->name,
+ version);
/* stall the microcprocessor */
phy_write(phydev, MDIO_MMD_VEND1, UP_CONTROL,
UP_RUN_STALL | UP_RUN_STALL_OVERRIDE);
- debug("loading dram 0x%08x from offset=%d size=%d\n",
- DRAM_BASE_ADDR, dram_offset, dram_size);
+ debug("loading dram 0x%08x from offset=%d size=%d\n", DRAM_BASE_ADDR,
+ dram_offset, dram_size);
ret = aquantia_load_memory(phydev, DRAM_BASE_ADDR, &addr[dram_offset],
dram_size);
if (ret != 0)
goto done;
- debug("loading iram 0x%08x from offset=%d size=%d\n",
- IRAM_BASE_ADDR, iram_offset, iram_size);
+ debug("loading iram 0x%08x from offset=%d size=%d\n", IRAM_BASE_ADDR,
+ iram_offset, iram_size);
ret = aquantia_load_memory(phydev, IRAM_BASE_ADDR, &addr[iram_offset],
iram_size);
if (ret != 0)
@@ -306,14 +307,14 @@ struct {
int cnt;
u16 start_rate;
} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = {
- [PHY_INTERFACE_MODE_SGMII] = {0x04b, AQUANTIA_VND1_GSYSCFG_1G,
- AQUANTIA_VND1_GSTART_RATE_1G},
- [PHY_INTERFACE_MODE_2500BASEX] = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G,
- AQUANTIA_VND1_GSTART_RATE_2_5G},
- [PHY_INTERFACE_MODE_10GBASER] = {0x100, AQUANTIA_VND1_GSYSCFG_10G,
- AQUANTIA_VND1_GSTART_RATE_10G},
- [PHY_INTERFACE_MODE_USXGMII] = {0x080, AQUANTIA_VND1_GSYSCFG_10G,
- AQUANTIA_VND1_GSTART_RATE_10G},
+ [PHY_INTERFACE_MODE_SGMII] = { 0x04b, AQUANTIA_VND1_GSYSCFG_1G,
+ AQUANTIA_VND1_GSTART_RATE_1G },
+ [PHY_INTERFACE_MODE_2500BASEX] = { 0x144, AQUANTIA_VND1_GSYSCFG_2_5G,
+ AQUANTIA_VND1_GSTART_RATE_2_5G },
+ [PHY_INTERFACE_MODE_10GBASER] = { 0x100, AQUANTIA_VND1_GSYSCFG_10G,
+ AQUANTIA_VND1_GSTART_RATE_10G },
+ [PHY_INTERFACE_MODE_USXGMII] = { 0x080, AQUANTIA_VND1_GSYSCFG_10G,
+ AQUANTIA_VND1_GSTART_RATE_10G },
};
static int aquantia_set_proto(struct phy_device *phydev,
@@ -352,8 +353,8 @@ static int aquantia_dts_config(struct phy_device *phydev)
if (!ofnode_read_u32(node, "mdi-reversal", &prop)) {
debug("mdi-reversal = %d\n", (int)prop);
- reg = phy_read(phydev, MDIO_MMD_PMAPMD,
- AQUANTIA_PMA_RX_VENDOR_P1);
+ reg = phy_read(phydev, MDIO_MMD_PMAPMD,
+ AQUANTIA_PMA_RX_VENDOR_P1);
reg &= ~AQUANTIA_PMA_RX_VENDOR_P1_MDI_MSK;
reg |= AQUANTIA_PMA_RX_VENDOR_P1_MDI_CFG;
reg |= prop ? AQUANTIA_PMA_RX_VENDOR_P1_MDI_REV : 0;
@@ -501,11 +502,11 @@ int aquantia_config(struct phy_device *phydev)
!(val & AQUNTIA_SPEED_MSB_MASK))
phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR,
AQUNTIA_SPEED_LSB_MASK |
- AQUNTIA_SPEED_MSB_MASK);
+ AQUNTIA_SPEED_MSB_MASK);
/* If SI is USXGMII then start USXGMII autoneg */
- reg_val1 = phy_read(phydev, MDIO_MMD_PHYXS,
- AQUANTIA_VENDOR_PROVISIONING_REG);
+ reg_val1 = phy_read(phydev, MDIO_MMD_PHYXS,
+ AQUANTIA_VENDOR_PROVISIONING_REG);
if (usx_an) {
reg_val1 |= AQUANTIA_USX_AUTONEG_CONTROL_ENA;
@@ -542,8 +543,7 @@ int aquantia_config(struct phy_device *phydev)
reg_val1 = phy_read(phydev, MDIO_MMD_VEND1, AQUANTIA_FIRMWARE_ID);
debug("%s: %s Firmware Version %x.%x.%x\n", phydev->dev->name,
- phydev->drv->name,
- (reg_val1 & AQUANTIA_FIRMWARE_MAJOR_MASK) >> 8,
+ phydev->drv->name, (reg_val1 & AQUANTIA_FIRMWARE_MAJOR_MASK) >> 8,
reg_val1 & AQUANTIA_FIRMWARE_MINOR_MASK,
(val & AQUANTIA_FIRMWARE_BUILD_MASK) >> 4);
@@ -604,9 +604,8 @@ U_BOOT_PHY_DRIVER(aq1202) = {
.uid = 0x3a1b445,
.mask = 0xfffffff0,
.features = PHY_10G_FEATURES,
- .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
- MDIO_MMD_PHYXS | MDIO_MMD_AN |
- MDIO_MMD_VEND1),
+ .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS | MDIO_MMD_PHYXS | MDIO_MMD_AN |
+ MDIO_MMD_VEND1),
.config = &aquantia_config,
.startup = &aquantia_startup,
.shutdown = &gen10g_shutdown,
@@ -617,9 +616,8 @@ U_BOOT_PHY_DRIVER(aq2104) = {
.uid = 0x3a1b460,
.mask = 0xfffffff0,
.features = PHY_10G_FEATURES,
- .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
- MDIO_MMD_PHYXS | MDIO_MMD_AN |
- MDIO_MMD_VEND1),
+ .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS | MDIO_MMD_PHYXS | MDIO_MMD_AN |
+ MDIO_MMD_VEND1),
.config = &aquantia_config,
.startup = &aquantia_startup,
.shutdown = &gen10g_shutdown,
@@ -630,9 +628,8 @@ U_BOOT_PHY_DRIVER(aqr105) = {
.uid = 0x3a1b4a2,
.mask = 0xfffffff0,
.features = PHY_10G_FEATURES,
- .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
- MDIO_MMD_PHYXS | MDIO_MMD_AN |
- MDIO_MMD_VEND1),
+ .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS | MDIO_MMD_PHYXS | MDIO_MMD_AN |
+ MDIO_MMD_VEND1),
.config = &aquantia_config,
.startup = &aquantia_startup,
.shutdown = &gen10g_shutdown,
@@ -644,9 +641,8 @@ U_BOOT_PHY_DRIVER(aqr106) = {
.uid = 0x3a1b4d0,
.mask = 0xfffffff0,
.features = PHY_10G_FEATURES,
- .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
- MDIO_MMD_PHYXS | MDIO_MMD_AN |
- MDIO_MMD_VEND1),
+ .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS | MDIO_MMD_PHYXS | MDIO_MMD_AN |
+ MDIO_MMD_VEND1),
.config = &aquantia_config,
.startup = &aquantia_startup,
.shutdown = &gen10g_shutdown,
@@ -657,9 +653,8 @@ U_BOOT_PHY_DRIVER(aqr107) = {
.uid = 0x3a1b4e0,
.mask = 0xfffffff0,
.features = PHY_10G_FEATURES,
- .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
- MDIO_MMD_PHYXS | MDIO_MMD_AN |
- MDIO_MMD_VEND1),
+ .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS | MDIO_MMD_PHYXS | MDIO_MMD_AN |
+ MDIO_MMD_VEND1),
.config = &aquantia_config,
.startup = &aquantia_startup,
.shutdown = &gen10g_shutdown,
@@ -671,8 +666,7 @@ U_BOOT_PHY_DRIVER(aqr112) = {
.uid = 0x3a1b660,
.mask = 0xfffffff0,
.features = PHY_10G_FEATURES,
- .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS |
- MDIO_MMD_PHYXS | MDIO_MMD_AN |
+ .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS | MDIO_MMD_PHYXS | MDIO_MMD_AN |
MDIO_MMD_VEND1),
.config = &aquantia_config,
.startup = &aquantia_startup,
@@ -685,8 +679,7 @@ U_BOOT_PHY_DRIVER(aqr113c) = {
.uid = 0x31c31c12,
.mask = 0xfffffff0,
.features = PHY_10G_FEATURES,
- .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS |
- MDIO_MMD_PHYXS | MDIO_MMD_AN |
+ .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS | MDIO_MMD_PHYXS | MDIO_MMD_AN |
MDIO_MMD_VEND1),
.config = &aquantia_config,
.startup = &aquantia_startup,
@@ -699,8 +692,7 @@ U_BOOT_PHY_DRIVER(aqr405) = {
.uid = 0x3a1b4b2,
.mask = 0xfffffff0,
.features = PHY_10G_FEATURES,
- .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
- MDIO_MMD_PHYXS | MDIO_MMD_AN |
+ .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS | MDIO_MMD_PHYXS | MDIO_MMD_AN |
MDIO_MMD_VEND1),
.config = &aquantia_config,
.startup = &aquantia_startup,
@@ -713,8 +705,7 @@ U_BOOT_PHY_DRIVER(aqr412) = {
.uid = 0x3a1b710,
.mask = 0xfffffff0,
.features = PHY_10G_FEATURES,
- .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS |
- MDIO_MMD_PHYXS | MDIO_MMD_AN |
+ .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS | MDIO_MMD_PHYXS | MDIO_MMD_AN |
MDIO_MMD_VEND1),
.config = &aquantia_config,
.startup = &aquantia_startup,
--
2.47.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v4 2/5] doc: bindings: use upstream bindings for aquantia phy
2025-10-31 15:21 [PATCH v4 0/5] net: phy: aquantia: Switch to generic firmware loader Beiyan Yun
2025-10-31 15:21 ` [PATCH v4 1/5] net: phy: aquantia: refresh format Beiyan Yun
@ 2025-10-31 15:21 ` Beiyan Yun
2025-10-31 15:53 ` Marek Vasut
2025-10-31 15:21 ` [PATCH v4 3/5] net: phy: aquantia: replace the "mdi-reversal" node with "marvell, mdi-cfg-order" Beiyan Yun
` (2 subsequent siblings)
4 siblings, 1 reply; 22+ messages in thread
From: Beiyan Yun @ 2025-10-31 15:21 UTC (permalink / raw)
To: u-boot; +Cc: Yao Zi, Marek Vasut, Tom Rini, Beiyan Yun
Prepare for the switch to upstream bindings and generic firmware loader,
remove reference to upstreamed bindings, also add a firmware-name example.
Signed-off-by: Beiyan Yun <root@infi.wang>
---
(no changes since v2)
Changes in v2:
- New
doc/device-tree-bindings/net/aquantia-phy.txt | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/doc/device-tree-bindings/net/aquantia-phy.txt b/doc/device-tree-bindings/net/aquantia-phy.txt
index 7dd3d45df12..80de0e8b158 100644
--- a/doc/device-tree-bindings/net/aquantia-phy.txt
+++ b/doc/device-tree-bindings/net/aquantia-phy.txt
@@ -1,25 +1,16 @@
PHY nodes for Aquantia devices.
This text describes properties that are applicable to Aquantia PHY nodes in
-addition to the bindings in phy.txt.
-
-Aquantia PHYs allow some flexibility in the way they are wired in a system,
-they allow MDI pins to be reversed, LEDs linked up in different ways, have an
-I2C slave interface that can be used for debug. Normally the configuration
-corresponding to these is driven by the PHY firmware with the downside that
-a custom firmware is needed for each integration of a PHY.
-Several optional bindings are defined that allow these configuration points to
-be driven by the PHY driver and reduce dependency on specific FW versions.
+addition to the bindings in upstream and phy.txt.
Optional properties:
-mdi-reversal: 0 or 1 indicating that reversal must be disabled/enabled.
- Firmware default is used if the property is missing.
smb-addr: I2C/SMBus address to use, firmware default is used if the property
is missing.
Example node:
phy@00 {
reg = <0x00>;
- mdi-reversal = <1>;
+ marvell,mdi-cfg-order = <1>;
smb-addr = <0x25>;
+ firmware-name = "aqr-firmware.cld";
};
--
2.47.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v4 3/5] net: phy: aquantia: replace the "mdi-reversal" node with "marvell, mdi-cfg-order"
2025-10-31 15:21 [PATCH v4 0/5] net: phy: aquantia: Switch to generic firmware loader Beiyan Yun
2025-10-31 15:21 ` [PATCH v4 1/5] net: phy: aquantia: refresh format Beiyan Yun
2025-10-31 15:21 ` [PATCH v4 2/5] doc: bindings: use upstream bindings for aquantia phy Beiyan Yun
@ 2025-10-31 15:21 ` Beiyan Yun
2025-10-31 15:21 ` [PATCH v4 4/5] net: phy: aquantia: refactor firmware upload helpers Beiyan Yun
2025-10-31 15:21 ` [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader Beiyan Yun
4 siblings, 0 replies; 22+ messages in thread
From: Beiyan Yun @ 2025-10-31 15:21 UTC (permalink / raw)
To: u-boot
Cc: Yao Zi, Marek Vasut, Tom Rini, Beiyan Yun, Jerome Forissier,
Joe Hershberger, Ramon Fried, Siddharth Vadapalli
As part of the effort of making U-Boot work with the same device tree as
Linux, align with upstream node name.
Signed-off-by: Beiyan Yun <root@infi.wang>
---
(no changes since v2)
Changes in v2:
- New
arch/arm/dts/fsl-sch-30841.dtsi | 8 ++++----
arch/arm/dts/fsl-sch-30842.dtsi | 2 +-
drivers/net/phy/aquantia.c | 4 ++--
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm/dts/fsl-sch-30841.dtsi b/arch/arm/dts/fsl-sch-30841.dtsi
index 28b1bec18a5..a92d9811fd3 100644
--- a/arch/arm/dts/fsl-sch-30841.dtsi
+++ b/arch/arm/dts/fsl-sch-30841.dtsi
@@ -15,24 +15,24 @@
*/
phy@00 {
reg = <0x00>;
- mdi-reversal = <1>;
+ marvell,mdi-cfg-order = <1>;
smb-addr = <0x25>;
};
phy@01 {
reg = <0x01>;
- mdi-reversal = <1>;
+ marvell,mdi-cfg-order = <1>;
smb-addr = <0x26>;
};
phy@02 {
reg = <0x02>;
- mdi-reversal = <1>;
+ marvell,mdi-cfg-order = <1>;
smb-addr = <0x27>;
};
phy@03 {
reg = <0x03>;
- mdi-reversal = <1>;
+ marvell,mdi-cfg-order = <1>;
smb-addr = <0x28>;
};
diff --git a/arch/arm/dts/fsl-sch-30842.dtsi b/arch/arm/dts/fsl-sch-30842.dtsi
index bff9e76570b..fca38d14975 100644
--- a/arch/arm/dts/fsl-sch-30842.dtsi
+++ b/arch/arm/dts/fsl-sch-30842.dtsi
@@ -13,6 +13,6 @@
*/
phy@02 {
reg = <0x02>;
- mdi-reversal = <1>;
+ marvell,mdi-cfg-order = <1>;
smb-addr = <0x25>;
};
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 439c4c48bdc..11e450cdb0b 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -351,8 +351,8 @@ static int aquantia_dts_config(struct phy_device *phydev)
if (!ofnode_valid(node))
return 0;
- if (!ofnode_read_u32(node, "mdi-reversal", &prop)) {
- debug("mdi-reversal = %d\n", (int)prop);
+ if (!ofnode_read_u32(node, "marvell,mdi-cfg-order", &prop)) {
+ debug("marvell,mdi-cfg-order = %d\n", (int)prop);
reg = phy_read(phydev, MDIO_MMD_PMAPMD,
AQUANTIA_PMA_RX_VENDOR_P1);
reg &= ~AQUANTIA_PMA_RX_VENDOR_P1_MDI_MSK;
--
2.47.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v4 4/5] net: phy: aquantia: refactor firmware upload helpers
2025-10-31 15:21 [PATCH v4 0/5] net: phy: aquantia: Switch to generic firmware loader Beiyan Yun
` (2 preceding siblings ...)
2025-10-31 15:21 ` [PATCH v4 3/5] net: phy: aquantia: replace the "mdi-reversal" node with "marvell, mdi-cfg-order" Beiyan Yun
@ 2025-10-31 15:21 ` Beiyan Yun
2025-10-31 15:21 ` [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader Beiyan Yun
4 siblings, 0 replies; 22+ messages in thread
From: Beiyan Yun @ 2025-10-31 15:21 UTC (permalink / raw)
To: u-boot
Cc: Yao Zi, Marek Vasut, Tom Rini, Beiyan Yun, Jerome Forissier,
Joe Hershberger, Ramon Fried, Siddharth Vadapalli
Split `aquantia_upload_firmware` into `aquantia_upload_firmware`
and `aquantia_do_upload_firmware` to prepare for fsloader change.
Signed-off-by: Beiyan Yun <root@infi.wang>
Patch-cc:marek
---
Changes in v4:
- New
drivers/net/phy/aquantia.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 11e450cdb0b..461d4b07a40 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -218,27 +218,21 @@ static u32 unpack_u24(const u8 *data)
return (data[2] << 16) + (data[1] << 8) + data[0];
}
-static int aquantia_upload_firmware(struct phy_device *phydev)
+static int aquantia_do_upload_firmware(struct phy_device *phydev,
+ const u8 *addr, size_t fw_length)
{
int ret;
- u8 *addr = NULL;
- size_t fw_length = 0;
u16 calculated_crc, read_crc;
char version[VERSION_STRING_SIZE];
u32 primary_offset, iram_offset, iram_size, dram_offset, dram_size;
const struct fw_header *header;
- ret = aquantia_read_fw(&addr, &fw_length);
- if (ret != 0)
- return ret;
-
read_crc = (addr[fw_length - 2] << 8) | addr[fw_length - 1];
calculated_crc = crc16_ccitt(0, addr, fw_length - 2);
if (read_crc != calculated_crc) {
printf("%s bad firmware crc: file 0x%04x calculated 0x%04x\n",
phydev->dev->name, read_crc, calculated_crc);
- ret = -EINVAL;
- goto done;
+ return -EINVAL;
}
/* Find the DRAM and IRAM sections within the firmware file. */
@@ -269,14 +263,14 @@ static int aquantia_upload_firmware(struct phy_device *phydev)
ret = aquantia_load_memory(phydev, DRAM_BASE_ADDR, &addr[dram_offset],
dram_size);
if (ret != 0)
- goto done;
+ return ret;
debug("loading iram 0x%08x from offset=%d size=%d\n", IRAM_BASE_ADDR,
iram_offset, iram_size);
ret = aquantia_load_memory(phydev, IRAM_BASE_ADDR, &addr[iram_offset],
iram_size);
if (ret != 0)
- goto done;
+ return ret;
/* make sure soft reset and low power mode are clear */
phy_write(phydev, MDIO_MMD_VEND1, GLOBAL_STANDARD_CONTROL, 0);
@@ -290,8 +284,24 @@ static int aquantia_upload_firmware(struct phy_device *phydev)
phy_write(phydev, MDIO_MMD_VEND1, UP_CONTROL, UP_RUN_STALL_OVERRIDE);
printf("%s firmware loading done.\n", phydev->dev->name);
-done:
+
+ return 0;
+}
+
+static int aquantia_upload_firmware(struct phy_device *phydev)
+{
+ int ret;
+ u8 *addr = NULL;
+ size_t fw_length = 0;
+
+ ret = aquantia_read_fw(&addr, &fw_length);
+ if (ret != 0)
+ return ret;
+
+ ret = aquantia_do_upload_firmware(phydev, addr, fw_length);
+
free(addr);
+
return ret;
}
#else
--
2.47.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader
2025-10-31 15:21 [PATCH v4 0/5] net: phy: aquantia: Switch to generic firmware loader Beiyan Yun
` (3 preceding siblings ...)
2025-10-31 15:21 ` [PATCH v4 4/5] net: phy: aquantia: refactor firmware upload helpers Beiyan Yun
@ 2025-10-31 15:21 ` Beiyan Yun
2025-10-31 15:41 ` Daniel Golle
2025-10-31 15:57 ` Marek Vasut
4 siblings, 2 replies; 22+ messages in thread
From: Beiyan Yun @ 2025-10-31 15:21 UTC (permalink / raw)
To: u-boot
Cc: Yao Zi, Marek Vasut, Tom Rini, Beiyan Yun, Jerome Forissier,
Joe Hershberger, Lucien.Jheng, Ramon Fried, Romain Gantois,
Siddharth Vadapalli, Weijie Gao
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 firmware loader to
allow a wider range and runtime override of firmware source. (e.g., USB).
Tested on Buffalo WXR18000BE10P with UBIFS.
Signed-off-by: Beiyan Yun <root@infi.wang>
---
Changes in v4:
- Split firmware upload helpers change
- Reorder `aquantia_read_fw`
- Make `aquantia_read_fw` weak to allow overide
- Rename exit label in `aquantia_read_fw`
- Kconfig polish
Changes in v3:
- Select FW_LOADER with PHY_AQUANTIA_UPLOAD_FW
Changes in v2:
- Add support for script based loader
drivers/net/phy/Kconfig | 28 +++++----
drivers/net/phy/aquantia.c | 122 ++++++++++++++++++++++---------------
2 files changed, 91 insertions(+), 59 deletions(-)
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 018be98705a..4a74a0d4e8c 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -1,4 +1,3 @@
-
config BITBANGMII
bool "Bit-banged ethernet MII management channel support"
@@ -91,23 +90,30 @@ menuconfig PHY_AQUANTIA
config PHY_AQUANTIA_UPLOAD_FW
bool "Aquantia firmware loading support"
depends on PHY_AQUANTIA
+ select FS_LOADER
+ 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.
+
+ This option enables loading the firmware using the generic
+ firmware loader framework.
-config PHY_AQUANTIA_FW_PART
- string "Aquantia firmware partition"
+config PHY_AQUANTIA_FW_MAX_SIZE
+ hex "Max firmware size"
depends on PHY_AQUANTIA_UPLOAD_FW
+ default 0x80000
help
- Partition containing the firmware file.
+ The maximum size of the Aquantia PHY firmware. This is used to
+ allocate a buffer to load the firmware into.
-config PHY_AQUANTIA_FW_NAME
- string "Aquantia firmware filename"
+config PHY_AQUANTIA_FW_LOADER_SCRIPT
+ string "Aquantia firmware loader script"
depends on PHY_AQUANTIA_UPLOAD_FW
+ default "aqr_phy_load_firmware"
help
- Firmware filename.
+ The firmware loading script variable name.
config PHY_ATHEROS
bool "Atheros Ethernet PHYs support"
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 461d4b07a40..934bd17eadd 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -17,6 +17,10 @@
#include <malloc.h>
#include <asm/byteorder.h>
#include <fs.h>
+#if (IS_ENABLED(CONFIG_PHY_AQUANTIA_UPLOAD_FW))
+#include <fs_loader.h>
+#include <fw_loader.h>
+#endif
#define AQUNTIA_10G_CTL 0x20
#define AQUNTIA_VENDOR_P1 0xc400
@@ -127,51 +131,67 @@ 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;
+ ofnode node;
+ struct udevice *loader_dev;
+ const char *fw_name;
+ u8 *tmp_fw_addr;
+ size_t tmp_fw_length;
+
+ tmp_fw_addr = malloc(CONFIG_PHY_AQUANTIA_FW_MAX_SIZE);
+ if (!tmp_fw_addr) {
+ printf("Failed to allocate memory for firmware\n");
+ return -ENOMEM;
}
- 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;
-
- *fw_addr = addr;
- *fw_length = length;
- debug("Found Aquantia microcode.\n");
-
-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);
+ /* First, try to load firmware via script */
+ ret = request_firmware_into_buf_via_script(
+ tmp_fw_addr, CONFIG_PHY_AQUANTIA_FW_MAX_SIZE,
+ CONFIG_PHY_AQUANTIA_FW_LOADER_SCRIPT, &tmp_fw_length);
+ if (ret) {
+ /* Fallback to DT specified firmware */
+ node = phy_get_ofnode(phydev);
+ if (!ofnode_valid(node)) {
+ printf("Failed to get PHY node\n");
+ ret = -EINVAL;
+ goto fail_free;
+ }
+
+ fw_name = ofnode_read_string(node, "firmware-name");
+ if (!fw_name) {
+ printf("Failed to get firmware name\n");
+ ret = -ENOENT;
+ goto fail_free;
+ }
+
+ ret = get_fs_loader(&loader_dev);
+ if (ret) {
+ printf("Failed to get fs_loader instance: %d\n", ret);
+ goto fail_free;
+ }
+
+ ret = request_firmware_into_buf(loader_dev, fw_name,
+ tmp_fw_addr,
+ CONFIG_PHY_AQUANTIA_FW_MAX_SIZE,
+ 0);
+ if (ret < 0) {
+ printf("Failed to load firmware %s: %d\n", fw_name,
+ ret);
+ goto fail_free;
+ }
+ tmp_fw_length = ret;
}
+
+ *fw_addr = tmp_fw_addr;
+ *fw_length = tmp_fw_length;
+ return 1;
+
+fail_free:
+ free(tmp_fw_addr);
return ret;
}
@@ -227,6 +247,11 @@ static int aquantia_do_upload_firmware(struct phy_device *phydev,
u32 primary_offset, iram_offset, iram_size, dram_offset, dram_size;
const struct fw_header *header;
+ if (!addr || !fw_length) {
+ printf("%s: Invalid firmware data\n", phydev->dev->name);
+ return -EINVAL;
+ }
+
read_crc = (addr[fw_length - 2] << 8) | addr[fw_length - 1];
calculated_crc = crc16_ccitt(0, addr, fw_length - 2);
if (read_crc != calculated_crc) {
@@ -290,17 +315,18 @@ static int aquantia_do_upload_firmware(struct phy_device *phydev,
static int aquantia_upload_firmware(struct phy_device *phydev)
{
- int ret;
- u8 *addr = NULL;
- size_t fw_length = 0;
+ int ret, fwrc;
+ u8 *fw_addr = NULL;
+ size_t fw_length;
- ret = aquantia_read_fw(&addr, &fw_length);
- if (ret != 0)
- return ret;
+ fwrc = aquantia_read_fw(phydev, &fw_addr, &fw_length);
+ if (fwrc < 0)
+ return fwrc;
- ret = aquantia_do_upload_firmware(phydev, addr, fw_length);
+ ret = aquantia_do_upload_firmware(phydev, fw_addr, fw_length);
- free(addr);
+ if (fwrc > 0)
+ free(fw_addr);
return ret;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader
2025-10-31 15:21 ` [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader Beiyan Yun
@ 2025-10-31 15:41 ` Daniel Golle
2025-10-31 16:09 ` Beiyan Yun
2025-10-31 15:57 ` Marek Vasut
1 sibling, 1 reply; 22+ messages in thread
From: Daniel Golle @ 2025-10-31 15:41 UTC (permalink / raw)
To: Beiyan Yun
Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier,
Joe Hershberger, Lucien.Jheng, Ramon Fried, Romain Gantois,
Siddharth Vadapalli, Weijie Gao
On Fri, Oct 31, 2025 at 11:21:07PM +0800, Beiyan Yun wrote:
> 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 firmware loader to
> allow a wider range and runtime override of firmware source. (e.g., USB).
>
> Tested on Buffalo WXR18000BE10P with UBIFS.
Does the Buffalo WXR18000BE10P use UBIFS as rootfs out-of-the-box, and
include the Aquatia firmware there?
I'm asking because most of the devices supported in OpenWrt don't use
UBIFS on UBI but typically use a squashfs volume, or even a squashfs
filesystem or cpio.gz embedded into the uImage.FIT which is stored
directly on a UBI volume (and not as a file within UBIFS).
Hence it would be crucial to make sure that using
request_firmware_into_buf_via_script()
works for those devices which do not store the firmware on a filesystem
which is directly accessible within U-Boot.
Imho that's also better than using a __weak symbol as it would allow
implementing the board-specific method for acquiring the firmware as a
script rather than having to write C code for each board.
>
> Signed-off-by: Beiyan Yun <root@infi.wang>
> ---
>
> Changes in v4:
> - Split firmware upload helpers change
> - Reorder `aquantia_read_fw`
> - Make `aquantia_read_fw` weak to allow overide
> - Rename exit label in `aquantia_read_fw`
> - Kconfig polish
>
> Changes in v3:
> - Select FW_LOADER with PHY_AQUANTIA_UPLOAD_FW
>
> Changes in v2:
> - Add support for script based loader
>
> drivers/net/phy/Kconfig | 28 +++++----
> drivers/net/phy/aquantia.c | 122 ++++++++++++++++++++++---------------
> 2 files changed, 91 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index 018be98705a..4a74a0d4e8c 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -1,4 +1,3 @@
> -
> config BITBANGMII
> bool "Bit-banged ethernet MII management channel support"
>
> @@ -91,23 +90,30 @@ menuconfig PHY_AQUANTIA
> config PHY_AQUANTIA_UPLOAD_FW
> bool "Aquantia firmware loading support"
> depends on PHY_AQUANTIA
> + select FS_LOADER
> + 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.
> +
> + This option enables loading the firmware using the generic
> + firmware loader framework.
>
> -config PHY_AQUANTIA_FW_PART
> - string "Aquantia firmware partition"
> +config PHY_AQUANTIA_FW_MAX_SIZE
> + hex "Max firmware size"
> depends on PHY_AQUANTIA_UPLOAD_FW
> + default 0x80000
> help
> - Partition containing the firmware file.
> + The maximum size of the Aquantia PHY firmware. This is used to
> + allocate a buffer to load the firmware into.
>
> -config PHY_AQUANTIA_FW_NAME
> - string "Aquantia firmware filename"
> +config PHY_AQUANTIA_FW_LOADER_SCRIPT
> + string "Aquantia firmware loader script"
> depends on PHY_AQUANTIA_UPLOAD_FW
> + default "aqr_phy_load_firmware"
> help
> - Firmware filename.
> + The firmware loading script variable name.
>
> config PHY_ATHEROS
> bool "Atheros Ethernet PHYs support"
> diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
> index 461d4b07a40..934bd17eadd 100644
> --- a/drivers/net/phy/aquantia.c
> +++ b/drivers/net/phy/aquantia.c
> @@ -17,6 +17,10 @@
> #include <malloc.h>
> #include <asm/byteorder.h>
> #include <fs.h>
> +#if (IS_ENABLED(CONFIG_PHY_AQUANTIA_UPLOAD_FW))
> +#include <fs_loader.h>
> +#include <fw_loader.h>
> +#endif
>
> #define AQUNTIA_10G_CTL 0x20
> #define AQUNTIA_VENDOR_P1 0xc400
> @@ -127,51 +131,67 @@ 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;
> + ofnode node;
> + struct udevice *loader_dev;
> + const char *fw_name;
> + u8 *tmp_fw_addr;
> + size_t tmp_fw_length;
> +
> + tmp_fw_addr = malloc(CONFIG_PHY_AQUANTIA_FW_MAX_SIZE);
> + if (!tmp_fw_addr) {
> + printf("Failed to allocate memory for firmware\n");
> + return -ENOMEM;
> }
>
> - 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;
> -
> - *fw_addr = addr;
> - *fw_length = length;
> - debug("Found Aquantia microcode.\n");
> -
> -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);
> + /* First, try to load firmware via script */
> + ret = request_firmware_into_buf_via_script(
> + tmp_fw_addr, CONFIG_PHY_AQUANTIA_FW_MAX_SIZE,
> + CONFIG_PHY_AQUANTIA_FW_LOADER_SCRIPT, &tmp_fw_length);
> + if (ret) {
> + /* Fallback to DT specified firmware */
> + node = phy_get_ofnode(phydev);
> + if (!ofnode_valid(node)) {
> + printf("Failed to get PHY node\n");
> + ret = -EINVAL;
> + goto fail_free;
> + }
> +
> + fw_name = ofnode_read_string(node, "firmware-name");
> + if (!fw_name) {
> + printf("Failed to get firmware name\n");
> + ret = -ENOENT;
> + goto fail_free;
> + }
> +
> + ret = get_fs_loader(&loader_dev);
> + if (ret) {
> + printf("Failed to get fs_loader instance: %d\n", ret);
> + goto fail_free;
> + }
> +
> + ret = request_firmware_into_buf(loader_dev, fw_name,
> + tmp_fw_addr,
> + CONFIG_PHY_AQUANTIA_FW_MAX_SIZE,
> + 0);
> + if (ret < 0) {
> + printf("Failed to load firmware %s: %d\n", fw_name,
> + ret);
> + goto fail_free;
> + }
> + tmp_fw_length = ret;
> }
> +
> + *fw_addr = tmp_fw_addr;
> + *fw_length = tmp_fw_length;
> + return 1;
> +
> +fail_free:
> + free(tmp_fw_addr);
> return ret;
> }
>
> @@ -227,6 +247,11 @@ static int aquantia_do_upload_firmware(struct phy_device *phydev,
> u32 primary_offset, iram_offset, iram_size, dram_offset, dram_size;
> const struct fw_header *header;
>
> + if (!addr || !fw_length) {
> + printf("%s: Invalid firmware data\n", phydev->dev->name);
> + return -EINVAL;
> + }
> +
> read_crc = (addr[fw_length - 2] << 8) | addr[fw_length - 1];
> calculated_crc = crc16_ccitt(0, addr, fw_length - 2);
> if (read_crc != calculated_crc) {
> @@ -290,17 +315,18 @@ static int aquantia_do_upload_firmware(struct phy_device *phydev,
>
> static int aquantia_upload_firmware(struct phy_device *phydev)
> {
> - int ret;
> - u8 *addr = NULL;
> - size_t fw_length = 0;
> + int ret, fwrc;
> + u8 *fw_addr = NULL;
> + size_t fw_length;
>
> - ret = aquantia_read_fw(&addr, &fw_length);
> - if (ret != 0)
> - return ret;
> + fwrc = aquantia_read_fw(phydev, &fw_addr, &fw_length);
> + if (fwrc < 0)
> + return fwrc;
>
> - ret = aquantia_do_upload_firmware(phydev, addr, fw_length);
> + ret = aquantia_do_upload_firmware(phydev, fw_addr, fw_length);
>
> - free(addr);
> + if (fwrc > 0)
> + free(fw_addr);
>
> return ret;
> }
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 1/5] net: phy: aquantia: refresh format
2025-10-31 15:21 ` [PATCH v4 1/5] net: phy: aquantia: refresh format Beiyan Yun
@ 2025-10-31 15:51 ` Marek Vasut
2025-10-31 17:21 ` Beiyan Yun
0 siblings, 1 reply; 22+ messages in thread
From: Marek Vasut @ 2025-10-31 15:51 UTC (permalink / raw)
To: Beiyan Yun, u-boot
Cc: Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier, Joe Hershberger,
Ramon Fried, Siddharth Vadapalli
On 10/31/25 4:21 PM, Beiyan Yun wrote:
> Refresh format using clang-format.
>
> Signed-off-by: Beiyan Yun <root@infi.wang>
>
> ---
>
> Changes in v4:
> - New
>
> drivers/net/phy/aquantia.c | 159 +++++++++++++++++--------------------
> 1 file changed, 75 insertions(+), 84 deletions(-)
>
> diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
> index 903fcd667f6..439c4c48bdc 100644
> --- a/drivers/net/phy/aquantia.c
> +++ b/drivers/net/phy/aquantia.c
> @@ -18,28 +18,28 @@
> #include <asm/byteorder.h>
> #include <fs.h>
>
> -#define AQUNTIA_10G_CTL 0x20
> -#define AQUNTIA_VENDOR_P1 0xc400
> +#define AQUNTIA_10G_CTL 0x20
> +#define AQUNTIA_VENDOR_P1 0xc400
>
> -#define AQUNTIA_SPEED_LSB_MASK 0x2000
> -#define AQUNTIA_SPEED_MSB_MASK 0x40
> +#define AQUNTIA_SPEED_LSB_MASK 0x2000
> +#define AQUNTIA_SPEED_MSB_MASK 0x40
#define<space>MACRO<tab>0xvalue
is perfectly fine format.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 2/5] doc: bindings: use upstream bindings for aquantia phy
2025-10-31 15:21 ` [PATCH v4 2/5] doc: bindings: use upstream bindings for aquantia phy Beiyan Yun
@ 2025-10-31 15:53 ` Marek Vasut
2025-10-31 17:02 ` Beiyan Yun
0 siblings, 1 reply; 22+ messages in thread
From: Marek Vasut @ 2025-10-31 15:53 UTC (permalink / raw)
To: Beiyan Yun, u-boot; +Cc: Yao Zi, Marek Vasut, Tom Rini
On 10/31/25 4:21 PM, Beiyan Yun wrote:
> Prepare for the switch to upstream bindings and generic firmware loader,
> remove reference to upstreamed bindings, also add a firmware-name example.
>
> Signed-off-by: Beiyan Yun <root@infi.wang>
>
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - New
>
> doc/device-tree-bindings/net/aquantia-phy.txt | 15 +++------------
Upstream bindings are in YAML format:
Documentation/devicetree/bindings/net/marvell,aquantia.yaml
How come these bindings here are in text format ?
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader
2025-10-31 15:21 ` [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader Beiyan Yun
2025-10-31 15:41 ` Daniel Golle
@ 2025-10-31 15:57 ` Marek Vasut
2025-10-31 16:34 ` Beiyan Yun
1 sibling, 1 reply; 22+ messages in thread
From: Marek Vasut @ 2025-10-31 15:57 UTC (permalink / raw)
To: Beiyan Yun, u-boot
Cc: Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier, Joe Hershberger,
Lucien.Jheng, Ramon Fried, Romain Gantois, Siddharth Vadapalli,
Weijie Gao
On 10/31/25 4:21 PM, Beiyan Yun wrote:
> 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 firmware loader to
> allow a wider range and runtime override of firmware source. (e.g., USB).
>
> Tested on Buffalo WXR18000BE10P with UBIFS.
>
> Signed-off-by: Beiyan Yun <root@infi.wang>
> ---
>
> Changes in v4:
> - Split firmware upload helpers change
> - Reorder `aquantia_read_fw`
> - Make `aquantia_read_fw` weak to allow overide
> - Rename exit label in `aquantia_read_fw`
> - Kconfig polish
>
> Changes in v3:
> - Select FW_LOADER with PHY_AQUANTIA_UPLOAD_FW
>
> Changes in v2:
> - Add support for script based loader
>
> drivers/net/phy/Kconfig | 28 +++++----
> drivers/net/phy/aquantia.c | 122 ++++++++++++++++++++++---------------
> 2 files changed, 91 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index 018be98705a..4a74a0d4e8c 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -1,4 +1,3 @@
> -
> config BITBANGMII
> bool "Bit-banged ethernet MII management channel support"
>
> @@ -91,23 +90,30 @@ menuconfig PHY_AQUANTIA
> config PHY_AQUANTIA_UPLOAD_FW
> bool "Aquantia firmware loading support"
> depends on PHY_AQUANTIA
> + select FS_LOADER
> + select FW_LOADER
Can you not use the plain FW_LOADER to load the firmware from either
storage, UBI or Block ? Is FS_LOADER even needed ?
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader
2025-10-31 15:41 ` Daniel Golle
@ 2025-10-31 16:09 ` Beiyan Yun
0 siblings, 0 replies; 22+ messages in thread
From: Beiyan Yun @ 2025-10-31 16:09 UTC (permalink / raw)
To: Daniel Golle
Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier,
Joe Hershberger, Lucien.Jheng, Ramon Fried, Romain Gantois,
Siddharth Vadapalli, Weijie Gao
Hi Daniel,
> On 31 Oct 2025, at 11:41 PM, Daniel Golle <daniel@makrotopia.org> wrote:
>
> On Fri, Oct 31, 2025 at 11:21:07PM +0800, Beiyan Yun wrote:
>> 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 firmware loader to
>> allow a wider range and runtime override of firmware source. (e.g., USB).
>>
>> Tested on Buffalo WXR18000BE10P with UBIFS.
>
> Does the Buffalo WXR18000BE10P use UBIFS as rootfs out-of-the-box, and
> include the Aquatia firmware there?
>
No, it’s part of my WIP porting and ubootmod, as a) vendor layout is (unfortunately) UBI on NMBM, and b) for some hardware and/or Linux quirks I can’t make one of the two CUX3410 work without a soft PHY reset. Bring it up in U-Boot not only solves this, but also gives us two more usable port in U-Boot as a bonus.
I opened a OpenWrt forum thread at https://forum.openwrt.org/t/adding-support-for-buffalo-wxr18000be10p-mediatek-mt7988a/239795 if you’re interested.
> I'm asking because most of the devices supported in OpenWrt don't use
> UBIFS on UBI but typically use a squashfs volume, or even a squashfs
> filesystem or cpio.gz embedded into the uImage.FIT which is stored
> directly on a UBI volume (and not as a file within UBIFS).
>
I agree, UBIFS here is more about PoC, and a single `firmware` UBI part is comparable to similar implementation like some Airoha board's `en8811-fw`. We might read from overlay, though that could be too complicated in U-Boot?
> Hence it would be crucial to make sure that using
> request_firmware_into_buf_via_script()
> works for those devices which do not store the firmware on a filesystem
> which is directly accessible within U-Boot.
> Imho that's also better than using a __weak symbol as it would allow
> implementing the board-specific method for acquiring the firmware as a
> script rather than having to write C code for each board.
>
FW_LOADER support (request_firmware_into_buf_via_script) is available since patch v2 ;)
>>
>> Signed-off-by: Beiyan Yun <root@infi.wang>
>> ---
>>
>> Changes in v4:
>> - Split firmware upload helpers change
>> - Reorder `aquantia_read_fw`
>> - Make `aquantia_read_fw` weak to allow overide
>> - Rename exit label in `aquantia_read_fw`
>> - Kconfig polish
>>
>> Changes in v3:
>> - Select FW_LOADER with PHY_AQUANTIA_UPLOAD_FW
>>
>> Changes in v2:
>> - Add support for script based loader
>>
>> drivers/net/phy/Kconfig | 28 +++++----
>> drivers/net/phy/aquantia.c | 122 ++++++++++++++++++++++---------------
>> 2 files changed, 91 insertions(+), 59 deletions(-)
>>
>> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
>> index 018be98705a..4a74a0d4e8c 100644
>> --- a/drivers/net/phy/Kconfig
>> +++ b/drivers/net/phy/Kconfig
>> @@ -1,4 +1,3 @@
>> -
>> config BITBANGMII
>> bool "Bit-banged ethernet MII management channel support"
>>
>> @@ -91,23 +90,30 @@ menuconfig PHY_AQUANTIA
>> config PHY_AQUANTIA_UPLOAD_FW
>> bool "Aquantia firmware loading support"
>> depends on PHY_AQUANTIA
>> + select FS_LOADER
>> + 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.
>> +
>> + This option enables loading the firmware using the generic
>> + firmware loader framework.
>>
>> -config PHY_AQUANTIA_FW_PART
>> - string "Aquantia firmware partition"
>> +config PHY_AQUANTIA_FW_MAX_SIZE
>> + hex "Max firmware size"
>> depends on PHY_AQUANTIA_UPLOAD_FW
>> + default 0x80000
>> help
>> - Partition containing the firmware file.
>> + The maximum size of the Aquantia PHY firmware. This is used to
>> + allocate a buffer to load the firmware into.
>>
>> -config PHY_AQUANTIA_FW_NAME
>> - string "Aquantia firmware filename"
>> +config PHY_AQUANTIA_FW_LOADER_SCRIPT
>> + string "Aquantia firmware loader script"
>> depends on PHY_AQUANTIA_UPLOAD_FW
>> + default "aqr_phy_load_firmware"
>> help
>> - Firmware filename.
>> + The firmware loading script variable name.
>>
>> config PHY_ATHEROS
>> bool "Atheros Ethernet PHYs support"
>> diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
>> index 461d4b07a40..934bd17eadd 100644
>> --- a/drivers/net/phy/aquantia.c
>> +++ b/drivers/net/phy/aquantia.c
>> @@ -17,6 +17,10 @@
>> #include <malloc.h>
>> #include <asm/byteorder.h>
>> #include <fs.h>
>> +#if (IS_ENABLED(CONFIG_PHY_AQUANTIA_UPLOAD_FW))
>> +#include <fs_loader.h>
>> +#include <fw_loader.h>
>> +#endif
>>
>> #define AQUNTIA_10G_CTL 0x20
>> #define AQUNTIA_VENDOR_P1 0xc400
>> @@ -127,51 +131,67 @@ 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;
>> + ofnode node;
>> + struct udevice *loader_dev;
>> + const char *fw_name;
>> + u8 *tmp_fw_addr;
>> + size_t tmp_fw_length;
>> +
>> + tmp_fw_addr = malloc(CONFIG_PHY_AQUANTIA_FW_MAX_SIZE);
>> + if (!tmp_fw_addr) {
>> + printf("Failed to allocate memory for firmware\n");
>> + return -ENOMEM;
>> }
>>
>> - 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;
>> -
>> - *fw_addr = addr;
>> - *fw_length = length;
>> - debug("Found Aquantia microcode.\n");
>> -
>> -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);
>> + /* First, try to load firmware via script */
>> + ret = request_firmware_into_buf_via_script(
>> + tmp_fw_addr, CONFIG_PHY_AQUANTIA_FW_MAX_SIZE,
>> + CONFIG_PHY_AQUANTIA_FW_LOADER_SCRIPT, &tmp_fw_length);
>> + if (ret) {
>> + /* Fallback to DT specified firmware */
>> + node = phy_get_ofnode(phydev);
>> + if (!ofnode_valid(node)) {
>> + printf("Failed to get PHY node\n");
>> + ret = -EINVAL;
>> + goto fail_free;
>> + }
>> +
>> + fw_name = ofnode_read_string(node, "firmware-name");
>> + if (!fw_name) {
>> + printf("Failed to get firmware name\n");
>> + ret = -ENOENT;
>> + goto fail_free;
>> + }
>> +
>> + ret = get_fs_loader(&loader_dev);
>> + if (ret) {
>> + printf("Failed to get fs_loader instance: %d\n", ret);
>> + goto fail_free;
>> + }
>> +
>> + ret = request_firmware_into_buf(loader_dev, fw_name,
>> + tmp_fw_addr,
>> + CONFIG_PHY_AQUANTIA_FW_MAX_SIZE,
>> + 0);
>> + if (ret < 0) {
>> + printf("Failed to load firmware %s: %d\n", fw_name,
>> + ret);
>> + goto fail_free;
>> + }
>> + tmp_fw_length = ret;
>> }
>> +
>> + *fw_addr = tmp_fw_addr;
>> + *fw_length = tmp_fw_length;
>> + return 1;
>> +
>> +fail_free:
>> + free(tmp_fw_addr);
>> return ret;
>> }
>>
>> @@ -227,6 +247,11 @@ static int aquantia_do_upload_firmware(struct phy_device *phydev,
>> u32 primary_offset, iram_offset, iram_size, dram_offset, dram_size;
>> const struct fw_header *header;
>>
>> + if (!addr || !fw_length) {
>> + printf("%s: Invalid firmware data\n", phydev->dev->name);
>> + return -EINVAL;
>> + }
>> +
>> read_crc = (addr[fw_length - 2] << 8) | addr[fw_length - 1];
>> calculated_crc = crc16_ccitt(0, addr, fw_length - 2);
>> if (read_crc != calculated_crc) {
>> @@ -290,17 +315,18 @@ static int aquantia_do_upload_firmware(struct phy_device *phydev,
>>
>> static int aquantia_upload_firmware(struct phy_device *phydev)
>> {
>> - int ret;
>> - u8 *addr = NULL;
>> - size_t fw_length = 0;
>> + int ret, fwrc;
>> + u8 *fw_addr = NULL;
>> + size_t fw_length;
>>
>> - ret = aquantia_read_fw(&addr, &fw_length);
>> - if (ret != 0)
>> - return ret;
>> + fwrc = aquantia_read_fw(phydev, &fw_addr, &fw_length);
>> + if (fwrc < 0)
>> + return fwrc;
>>
>> - ret = aquantia_do_upload_firmware(phydev, addr, fw_length);
>> + ret = aquantia_do_upload_firmware(phydev, fw_addr, fw_length);
>>
>> - free(addr);
>> + if (fwrc > 0)
>> + free(fw_addr);
>>
>> return ret;
>> }
>> --
>> 2.47.3
>>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader
2025-10-31 15:57 ` Marek Vasut
@ 2025-10-31 16:34 ` Beiyan Yun
2025-10-31 16:51 ` Marek Vasut
0 siblings, 1 reply; 22+ messages in thread
From: Beiyan Yun @ 2025-10-31 16:34 UTC (permalink / raw)
To: Marek Vasut
Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier,
Joe Hershberger, Lucien.Jheng, Ramon Fried, Romain Gantois,
Siddharth Vadapalli, Weijie Gao
> On 31 Oct 2025, at 11:57 PM, Marek Vasut <marek.vasut@mailbox.org> wrote:
>
> On 10/31/25 4:21 PM, Beiyan Yun wrote:
>> 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 firmware loader to
>> allow a wider range and runtime override of firmware source. (e.g., USB).
>> Tested on Buffalo WXR18000BE10P with UBIFS.
>> Signed-off-by: Beiyan Yun <root@infi.wang>
>> ---
>> Changes in v4:
>> - Split firmware upload helpers change
>> - Reorder `aquantia_read_fw`
>> - Make `aquantia_read_fw` weak to allow overide
>> - Rename exit label in `aquantia_read_fw`
>> - Kconfig polish
>> Changes in v3:
>> - Select FW_LOADER with PHY_AQUANTIA_UPLOAD_FW
>> Changes in v2:
>> - Add support for script based loader
>> drivers/net/phy/Kconfig | 28 +++++----
>> drivers/net/phy/aquantia.c | 122 ++++++++++++++++++++++---------------
>> 2 files changed, 91 insertions(+), 59 deletions(-)
>> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
>> index 018be98705a..4a74a0d4e8c 100644
>> --- a/drivers/net/phy/Kconfig
>> +++ b/drivers/net/phy/Kconfig
>> @@ -1,4 +1,3 @@
>> -
>> config BITBANGMII
>> bool "Bit-banged ethernet MII management channel support"
>> @@ -91,23 +90,30 @@ menuconfig PHY_AQUANTIA
>> config PHY_AQUANTIA_UPLOAD_FW
>> bool "Aquantia firmware loading support"
>> depends on PHY_AQUANTIA
>> + select FS_LOADER
>> + select FW_LOADER
> Can you not use the plain FW_LOADER to load the firmware from either storage, UBI or Block ? Is FS_LOADER even needed ?
Thanks for the suggestion, and yes you can, but that API is script-only—it expects the board to stage the blob and just copies from the address exposed via *_addr/_size. The current users of this driver expect the old pattern: the bootloader mounts a filesystem (MMC before, now possibly UBI/USB/etc.), reads the firmware, and applies it. Keeping an fs-loader node in the DT is effectively the same contract as the legacy MMC setup, just generalized.
The fs_loader driver gives us several things the script path doesn’t: a standard way to describe the storage via "/chosen/firmware-loader", runtime overrides through "storage_interface/fw_dev_part/fw_ubi_*, and no requirement for a board-specific script. So FS_LOADER isn’t redundant—it’s the part that replaces the hard-coded MMC flow with a configurable backend, while the script helper stays available for boards that want extra logic.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader
2025-10-31 16:34 ` Beiyan Yun
@ 2025-10-31 16:51 ` Marek Vasut
2025-11-01 7:45 ` Beiyan Yun
0 siblings, 1 reply; 22+ messages in thread
From: Marek Vasut @ 2025-10-31 16:51 UTC (permalink / raw)
To: Beiyan Yun
Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier,
Joe Hershberger, Lucien.Jheng, Ramon Fried, Romain Gantois,
Siddharth Vadapalli, Weijie Gao
On 10/31/25 5:34 PM, Beiyan Yun wrote:
>
>
>> On 31 Oct 2025, at 11:57 PM, Marek Vasut <marek.vasut@mailbox.org> wrote:
>>
>> On 10/31/25 4:21 PM, Beiyan Yun wrote:
>>> 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 firmware loader to
>>> allow a wider range and runtime override of firmware source. (e.g., USB).
>>> Tested on Buffalo WXR18000BE10P with UBIFS.
>>> Signed-off-by: Beiyan Yun <root@infi.wang>
>>> ---
>>> Changes in v4:
>>> - Split firmware upload helpers change
>>> - Reorder `aquantia_read_fw`
>>> - Make `aquantia_read_fw` weak to allow overide
>>> - Rename exit label in `aquantia_read_fw`
>>> - Kconfig polish
>>> Changes in v3:
>>> - Select FW_LOADER with PHY_AQUANTIA_UPLOAD_FW
>>> Changes in v2:
>>> - Add support for script based loader
>>> drivers/net/phy/Kconfig | 28 +++++----
>>> drivers/net/phy/aquantia.c | 122 ++++++++++++++++++++++---------------
>>> 2 files changed, 91 insertions(+), 59 deletions(-)
>>> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
>>> index 018be98705a..4a74a0d4e8c 100644
>>> --- a/drivers/net/phy/Kconfig
>>> +++ b/drivers/net/phy/Kconfig
>>> @@ -1,4 +1,3 @@
>>> -
>>> config BITBANGMII
>>> bool "Bit-banged ethernet MII management channel support"
>>> @@ -91,23 +90,30 @@ menuconfig PHY_AQUANTIA
>>> config PHY_AQUANTIA_UPLOAD_FW
>>> bool "Aquantia firmware loading support"
>>> depends on PHY_AQUANTIA
>>> + select FS_LOADER
>>> + select FW_LOADER
>> Can you not use the plain FW_LOADER to load the firmware from either storage, UBI or Block ? Is FS_LOADER even needed ?
>
> Thanks for the suggestion, and yes you can, but that API is script-only—it expects the board to stage the blob and just copies from the address exposed via *_addr/_size. The current users of this driver expect the old pattern: the bootloader mounts a filesystem (MMC before, now possibly UBI/USB/etc.), reads the firmware, and applies it. Keeping an fs-loader node in the DT is effectively the same contract as the legacy MMC setup, just generalized.
Can you maybe write a script which implements the old loader behavior in
a compatible manner ?
> The fs_loader driver gives us several things the script path doesn’t: a standard way to describe the storage via "/chosen/firmware-loader"
Try this:
"fdt addr $fdtcontroladdr ; fdt print /chosen"
And then look at the "fdt" command and what it can do regarding reading
content of DT properties into variables.
> , runtime overrides through "storage_interface/fw_dev_part/fw_ubi_*, and no requirement for a board-specific script. So FS_LOADER isn’t redundant—it’s the part that replaces the hard-coded MMC flow with a configurable backend, while the script helper stays available for boards that want extra logic.
Maybe a more generic script can be a replacement for the older
hard-coded approach ?
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 2/5] doc: bindings: use upstream bindings for aquantia phy
2025-10-31 15:53 ` Marek Vasut
@ 2025-10-31 17:02 ` Beiyan Yun
2025-10-31 17:12 ` Marek Vasut
0 siblings, 1 reply; 22+ messages in thread
From: Beiyan Yun @ 2025-10-31 17:02 UTC (permalink / raw)
To: Marek Vasut; +Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini
> On 31 Oct 2025, at 11:53 PM, Marek Vasut <marek.vasut@mailbox.org> wrote:
>
> On 10/31/25 4:21 PM, Beiyan Yun wrote:
>> Prepare for the switch to upstream bindings and generic firmware loader,
>> remove reference to upstreamed bindings, also add a firmware-name example.
>> Signed-off-by: Beiyan Yun <root@infi.wang>
>> ---
>> (no changes since v2)
>> Changes in v2:
>> - New
>> doc/device-tree-bindings/net/aquantia-phy.txt | 15 +++------------
> Upstream bindings are in YAML format:
>
> Documentation/devicetree/bindings/net/marvell,aquantia.yaml
>
> How come these bindings here are in text format ?
As much as I’d like to, aquantia-phy.txt file has always been a plain-text binding in U-Boot; I only updated its contents to cleanup the upstreamed property names. Converting it to YAML would require a larger migration, one preferably upstreams smb-addr and eliminate the file entirely.
Since I have no interest, and don’t have hardware to validate the smb-addr quirk, I’d prefer to keep the local text binding as-is for NXP people.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 2/5] doc: bindings: use upstream bindings for aquantia phy
2025-10-31 17:02 ` Beiyan Yun
@ 2025-10-31 17:12 ` Marek Vasut
0 siblings, 0 replies; 22+ messages in thread
From: Marek Vasut @ 2025-10-31 17:12 UTC (permalink / raw)
To: Beiyan Yun; +Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini
On 10/31/25 6:02 PM, Beiyan Yun wrote:
>
>
>> On 31 Oct 2025, at 11:53 PM, Marek Vasut <marek.vasut@mailbox.org> wrote:
>>
>> On 10/31/25 4:21 PM, Beiyan Yun wrote:
>>> Prepare for the switch to upstream bindings and generic firmware loader,
>>> remove reference to upstreamed bindings, also add a firmware-name example.
>>> Signed-off-by: Beiyan Yun <root@infi.wang>
>>> ---
>>> (no changes since v2)
>>> Changes in v2:
>>> - New
>>> doc/device-tree-bindings/net/aquantia-phy.txt | 15 +++------------
>> Upstream bindings are in YAML format:
>>
>> Documentation/devicetree/bindings/net/marvell,aquantia.yaml
>>
>> How come these bindings here are in text format ?
> As much as I’d like to, aquantia-phy.txt file has always been a plain-text binding in U-Boot; I only updated its contents to cleanup the upstreamed property names. Converting it to YAML would require a larger migration, one preferably upstreams smb-addr and eliminate the file entirely.
Pull in the kernel YAML file, discard this txt file, and be done with it.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 1/5] net: phy: aquantia: refresh format
2025-10-31 15:51 ` Marek Vasut
@ 2025-10-31 17:21 ` Beiyan Yun
2025-10-31 18:33 ` Marek Vasut
0 siblings, 1 reply; 22+ messages in thread
From: Beiyan Yun @ 2025-10-31 17:21 UTC (permalink / raw)
To: Marek Vasut
Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier,
Joe Hershberger, Ramon Fried, Siddharth Vadapalli
> On 31 Oct 2025, at 11:51 PM, Marek Vasut <marek.vasut@mailbox.org> wrote:
>
> On 10/31/25 4:21 PM, Beiyan Yun wrote:
>> Refresh format using clang-format.
>> Signed-off-by: Beiyan Yun <root@infi.wang>
>> ---
>> Changes in v4:
>> - New
>> drivers/net/phy/aquantia.c | 159 +++++++++++++++++--------------------
>> 1 file changed, 75 insertions(+), 84 deletions(-)
>> diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
>> index 903fcd667f6..439c4c48bdc 100644
>> --- a/drivers/net/phy/aquantia.c
>> +++ b/drivers/net/phy/aquantia.c
>> @@ -18,28 +18,28 @@
>> #include <asm/byteorder.h>
>> #include <fs.h>
>> -#define AQUNTIA_10G_CTL 0x20
>> -#define AQUNTIA_VENDOR_P1 0xc400
>> +#define AQUNTIA_10G_CTL 0x20
>> +#define AQUNTIA_VENDOR_P1 0xc400
>> -#define AQUNTIA_SPEED_LSB_MASK 0x2000
>> -#define AQUNTIA_SPEED_MSB_MASK 0x40
>> +#define AQUNTIA_SPEED_LSB_MASK 0x2000
>> +#define AQUNTIA_SPEED_MSB_MASK 0x40
> #define<space>MACRO<tab>0xvalue
>
> is perfectly fine format.
Agree, until clang-format has become the default. I don’t really have a option.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 1/5] net: phy: aquantia: refresh format
2025-10-31 17:21 ` Beiyan Yun
@ 2025-10-31 18:33 ` Marek Vasut
2025-10-31 19:00 ` Tom Rini
0 siblings, 1 reply; 22+ messages in thread
From: Marek Vasut @ 2025-10-31 18:33 UTC (permalink / raw)
To: Beiyan Yun
Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier,
Joe Hershberger, Ramon Fried, Siddharth Vadapalli
On 10/31/25 6:21 PM, Beiyan Yun wrote:
>
>
>> On 31 Oct 2025, at 11:51 PM, Marek Vasut <marek.vasut@mailbox.org> wrote:
>>
>> On 10/31/25 4:21 PM, Beiyan Yun wrote:
>>> Refresh format using clang-format.
>>> Signed-off-by: Beiyan Yun <root@infi.wang>
>>> ---
>>> Changes in v4:
>>> - New
>>> drivers/net/phy/aquantia.c | 159 +++++++++++++++++--------------------
>>> 1 file changed, 75 insertions(+), 84 deletions(-)
>>> diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
>>> index 903fcd667f6..439c4c48bdc 100644
>>> --- a/drivers/net/phy/aquantia.c
>>> +++ b/drivers/net/phy/aquantia.c
>>> @@ -18,28 +18,28 @@
>>> #include <asm/byteorder.h>
>>> #include <fs.h>
>>> -#define AQUNTIA_10G_CTL 0x20
>>> -#define AQUNTIA_VENDOR_P1 0xc400
>>> +#define AQUNTIA_10G_CTL 0x20
>>> +#define AQUNTIA_VENDOR_P1 0xc400
>>> -#define AQUNTIA_SPEED_LSB_MASK 0x2000
>>> -#define AQUNTIA_SPEED_MSB_MASK 0x40
>>> +#define AQUNTIA_SPEED_LSB_MASK 0x2000
>>> +#define AQUNTIA_SPEED_MSB_MASK 0x40
>> #define<space>MACRO<tab>0xvalue
>>
>> is perfectly fine format.
>
> Agree, until clang-format has become the default.
This change makes readability worse, no matter what formatting tool is
the current recommendation.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 1/5] net: phy: aquantia: refresh format
2025-10-31 18:33 ` Marek Vasut
@ 2025-10-31 19:00 ` Tom Rini
0 siblings, 0 replies; 22+ messages in thread
From: Tom Rini @ 2025-10-31 19:00 UTC (permalink / raw)
To: Marek Vasut
Cc: Beiyan Yun, u-boot, Yao Zi, Marek Vasut, Jerome Forissier,
Joe Hershberger, Ramon Fried, Siddharth Vadapalli
[-- Attachment #1: Type: text/plain, Size: 1702 bytes --]
On Fri, Oct 31, 2025 at 07:33:13PM +0100, Marek Vasut wrote:
> On 10/31/25 6:21 PM, Beiyan Yun wrote:
> >
> >
> > > On 31 Oct 2025, at 11:51 PM, Marek Vasut <marek.vasut@mailbox.org> wrote:
> > >
> > > On 10/31/25 4:21 PM, Beiyan Yun wrote:
> > > > Refresh format using clang-format.
> > > > Signed-off-by: Beiyan Yun <root@infi.wang>
> > > > ---
> > > > Changes in v4:
> > > > - New
> > > > drivers/net/phy/aquantia.c | 159 +++++++++++++++++--------------------
> > > > 1 file changed, 75 insertions(+), 84 deletions(-)
> > > > diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
> > > > index 903fcd667f6..439c4c48bdc 100644
> > > > --- a/drivers/net/phy/aquantia.c
> > > > +++ b/drivers/net/phy/aquantia.c
> > > > @@ -18,28 +18,28 @@
> > > > #include <asm/byteorder.h>
> > > > #include <fs.h>
> > > > -#define AQUNTIA_10G_CTL 0x20
> > > > -#define AQUNTIA_VENDOR_P1 0xc400
> > > > +#define AQUNTIA_10G_CTL 0x20
> > > > +#define AQUNTIA_VENDOR_P1 0xc400
> > > > -#define AQUNTIA_SPEED_LSB_MASK 0x2000
> > > > -#define AQUNTIA_SPEED_MSB_MASK 0x40
> > > > +#define AQUNTIA_SPEED_LSB_MASK 0x2000
> > > > +#define AQUNTIA_SPEED_MSB_MASK 0x40
> > > #define<space>MACRO<tab>0xvalue
> > >
> > > is perfectly fine format.
> >
> > Agree, until clang-format has become the default.
> This change makes readability worse, no matter what formatting tool is the
> current recommendation.
Generally speaking, one should not just reformat the code, for
reformatting sake. If someone wants to tweak .clang-format and push the
changes to the kernel (whom I would assume are as picky as anyone else
here), that's fine with me.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader
2025-10-31 16:51 ` Marek Vasut
@ 2025-11-01 7:45 ` Beiyan Yun
2025-11-01 11:54 ` Marek Vasut
0 siblings, 1 reply; 22+ messages in thread
From: Beiyan Yun @ 2025-11-01 7:45 UTC (permalink / raw)
To: Marek Vasut
Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier,
Joe Hershberger, Lucien.Jheng, Ramon Fried, Romain Gantois,
Siddharth Vadapalli, Weijie Gao
> On 1 Nov 2025, at 12:51 AM, Marek Vasut <marek.vasut@mailbox.org> wrote:
>
> On 10/31/25 5:34 PM, Beiyan Yun wrote:
>>> On 31 Oct 2025, at 11:57 PM, Marek Vasut <marek.vasut@mailbox.org> wrote:
>>>
>>> On 10/31/25 4:21 PM, Beiyan Yun wrote:
>>>> 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 firmware loader to
>>>> allow a wider range and runtime override of firmware source. (e.g., USB).
>>>> Tested on Buffalo WXR18000BE10P with UBIFS.
>>>> Signed-off-by: Beiyan Yun <root@infi.wang>
>>>> ---
>>>> Changes in v4:
>>>> - Split firmware upload helpers change
>>>> - Reorder `aquantia_read_fw`
>>>> - Make `aquantia_read_fw` weak to allow overide
>>>> - Rename exit label in `aquantia_read_fw`
>>>> - Kconfig polish
>>>> Changes in v3:
>>>> - Select FW_LOADER with PHY_AQUANTIA_UPLOAD_FW
>>>> Changes in v2:
>>>> - Add support for script based loader
>>>> drivers/net/phy/Kconfig | 28 +++++----
>>>> drivers/net/phy/aquantia.c | 122 ++++++++++++++++++++++---------------
>>>> 2 files changed, 91 insertions(+), 59 deletions(-)
>>>> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
>>>> index 018be98705a..4a74a0d4e8c 100644
>>>> --- a/drivers/net/phy/Kconfig
>>>> +++ b/drivers/net/phy/Kconfig
>>>> @@ -1,4 +1,3 @@
>>>> -
>>>> config BITBANGMII
>>>> bool "Bit-banged ethernet MII management channel support"
>>>> @@ -91,23 +90,30 @@ menuconfig PHY_AQUANTIA
>>>> config PHY_AQUANTIA_UPLOAD_FW
>>>> bool "Aquantia firmware loading support"
>>>> depends on PHY_AQUANTIA
>>>> + select FS_LOADER
>>>> + select FW_LOADER
>>> Can you not use the plain FW_LOADER to load the firmware from either storage, UBI or Block ? Is FS_LOADER even needed ?
>> Thanks for the suggestion, and yes you can, but that API is script-only—it expects the board to stage the blob and just copies from the address exposed via *_addr/_size. The current users of this driver expect the old pattern: the bootloader mounts a filesystem (MMC before, now possibly UBI/USB/etc.), reads the firmware, and applies it. Keeping an fs-loader node in the DT is effectively the same contract as the legacy MMC setup, just generalized.
>
> Can you maybe write a script which implements the old loader behavior in a compatible manner ?
>
>> The fs_loader driver gives us several things the script path doesn’t: a standard way to describe the storage via "/chosen/firmware-loader"
>
> Try this:
>
> "fdt addr $fdtcontroladdr ; fdt print /chosen"
>
> And then look at the "fdt" command and what it can do regarding reading content of DT properties into variables.
>
>> , runtime overrides through "storage_interface/fw_dev_part/fw_ubi_*, and no requirement for a board-specific script. So FS_LOADER isn’t redundant—it’s the part that replaces the hard-coded MMC flow with a configurable backend, while the script helper stays available for boards that want extra logic.
> Maybe a more generic script can be a replacement for the older hard-coded approach ?
Fair enough, I’ll remove fsloader for now.
I still believe it would be valuable someday: if reading from nvmem cell is implemented, the same DT could be used for both U-Boot and Linux.
Regards,
Yun
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader
2025-11-01 7:45 ` Beiyan Yun
@ 2025-11-01 11:54 ` Marek Vasut
2025-11-02 4:57 ` Beiyan Yun
0 siblings, 1 reply; 22+ messages in thread
From: Marek Vasut @ 2025-11-01 11:54 UTC (permalink / raw)
To: Beiyan Yun
Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier,
Joe Hershberger, Lucien.Jheng, Ramon Fried, Romain Gantois,
Siddharth Vadapalli, Weijie Gao
On 11/1/25 8:45 AM, Beiyan Yun wrote:
Hi,
>>>> Can you not use the plain FW_LOADER to load the firmware from either storage, UBI or Block ? Is FS_LOADER even needed ?
>>> Thanks for the suggestion, and yes you can, but that API is script-only—it expects the board to stage the blob and just copies from the address exposed via *_addr/_size. The current users of this driver expect the old pattern: the bootloader mounts a filesystem (MMC before, now possibly UBI/USB/etc.), reads the firmware, and applies it. Keeping an fs-loader node in the DT is effectively the same contract as the legacy MMC setup, just generalized.
>>
>> Can you maybe write a script which implements the old loader behavior in a compatible manner ?
>>
>>> The fs_loader driver gives us several things the script path doesn’t: a standard way to describe the storage via "/chosen/firmware-loader"
>>
>> Try this:
>>
>> "fdt addr $fdtcontroladdr ; fdt print /chosen"
>>
>> And then look at the "fdt" command and what it can do regarding reading content of DT properties into variables.
>>
>>> , runtime overrides through "storage_interface/fw_dev_part/fw_ubi_*, and no requirement for a board-specific script. So FS_LOADER isn’t redundant—it’s the part that replaces the hard-coded MMC flow with a configurable backend, while the script helper stays available for boards that want extra logic.
>> Maybe a more generic script can be a replacement for the older hard-coded approach ?
>
> Fair enough, I’ll remove fsloader for now.
>
> I still believe it would be valuable someday: if reading from nvmem cell is implemented, the same DT could be used for both U-Boot and Linux.
See example above, you can read anything from the U-Boot control DT both
in U-Boot shell and in U-Boot env scripts, using 'fdt' command .
--
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader
2025-11-01 11:54 ` Marek Vasut
@ 2025-11-02 4:57 ` Beiyan Yun
2025-11-02 14:25 ` Marek Vasut
0 siblings, 1 reply; 22+ messages in thread
From: Beiyan Yun @ 2025-11-02 4:57 UTC (permalink / raw)
To: Marek Vasut
Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier,
Joe Hershberger, Lucien.Jheng, Ramon Fried, Romain Gantois,
Siddharth Vadapalli, Weijie Gao
> On 1 Nov 2025, at 7:54 PM, Marek Vasut <marek.vasut@mailbox.org> wrote:
>
> On 11/1/25 8:45 AM, Beiyan Yun wrote:
>
> Hi,
>
>>>>> Can you not use the plain FW_LOADER to load the firmware from either storage, UBI or Block ? Is FS_LOADER even needed ?
>>>> Thanks for the suggestion, and yes you can, but that API is script-only—it expects the board to stage the blob and just copies from the address exposed via *_addr/_size. The current users of this driver expect the old pattern: the bootloader mounts a filesystem (MMC before, now possibly UBI/USB/etc.), reads the firmware, and applies it. Keeping an fs-loader node in the DT is effectively the same contract as the legacy MMC setup, just generalized.
>>>
>>> Can you maybe write a script which implements the old loader behavior in a compatible manner ?
>>>
>>>> The fs_loader driver gives us several things the script path doesn’t: a standard way to describe the storage via "/chosen/firmware-loader"
>>>
>>> Try this:
>>>
>>> "fdt addr $fdtcontroladdr ; fdt print /chosen"
>>>
>>> And then look at the "fdt" command and what it can do regarding reading content of DT properties into variables.
>>>
>>>> , runtime overrides through "storage_interface/fw_dev_part/fw_ubi_*, and no requirement for a board-specific script. So FS_LOADER isn’t redundant—it’s the part that replaces the hard-coded MMC flow with a configurable backend, while the script helper stays available for boards that want extra logic.
>>> Maybe a more generic script can be a replacement for the older hard-coded approach ?
>> Fair enough, I’ll remove fsloader for now.
>> I still believe it would be valuable someday: if reading from nvmem cell is implemented, the same DT could be used for both U-Boot and Linux.
>
> See example above, you can read anything from the U-Boot control DT both in U-Boot shell and in U-Boot env scripts, using 'fdt' command .
>
To make sure I understand the preferred architecture: are you suggesting that FW_LOADER is the preferred method, and that all the logic for finding, mounting, and reading from storage should be handled by board-specific scripts that parse the DT using fdt?
My main objective with FS_LOADER was to provide a "zero-script" default for most common use case. While scripting is powerful, it seems beneficial to have a C-based driver that can natively read from a filesystem described by a standard DT binding, rather than requiring every board to script the same "find-and-mount" logic.
Am I overlooking al drawback to that C-based approach, or perhaps missing some prior discussion on this?
Thanks,
Yun
> --
> Best regards,
> Marek Vasut
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader
2025-11-02 4:57 ` Beiyan Yun
@ 2025-11-02 14:25 ` Marek Vasut
0 siblings, 0 replies; 22+ messages in thread
From: Marek Vasut @ 2025-11-02 14:25 UTC (permalink / raw)
To: Beiyan Yun
Cc: u-boot, Yao Zi, Marek Vasut, Tom Rini, Jerome Forissier,
Joe Hershberger, Lucien.Jheng, Ramon Fried, Romain Gantois,
Siddharth Vadapalli, Weijie Gao
On 11/2/25 5:57 AM, Beiyan Yun wrote:
Hi,
>>>>>> Can you not use the plain FW_LOADER to load the firmware from either storage, UBI or Block ? Is FS_LOADER even needed ?
>>>>> Thanks for the suggestion, and yes you can, but that API is script-only—it expects the board to stage the blob and just copies from the address exposed via *_addr/_size. The current users of this driver expect the old pattern: the bootloader mounts a filesystem (MMC before, now possibly UBI/USB/etc.), reads the firmware, and applies it. Keeping an fs-loader node in the DT is effectively the same contract as the legacy MMC setup, just generalized.
>>>>
>>>> Can you maybe write a script which implements the old loader behavior in a compatible manner ?
>>>>
>>>>> The fs_loader driver gives us several things the script path doesn’t: a standard way to describe the storage via "/chosen/firmware-loader"
>>>>
>>>> Try this:
>>>>
>>>> "fdt addr $fdtcontroladdr ; fdt print /chosen"
>>>>
>>>> And then look at the "fdt" command and what it can do regarding reading content of DT properties into variables.
>>>>
>>>>> , runtime overrides through "storage_interface/fw_dev_part/fw_ubi_*, and no requirement for a board-specific script. So FS_LOADER isn’t redundant—it’s the part that replaces the hard-coded MMC flow with a configurable backend, while the script helper stays available for boards that want extra logic.
>>>> Maybe a more generic script can be a replacement for the older hard-coded approach ?
>>> Fair enough, I’ll remove fsloader for now.
>>> I still believe it would be valuable someday: if reading from nvmem cell is implemented, the same DT could be used for both U-Boot and Linux.
>>
>> See example above, you can read anything from the U-Boot control DT both in U-Boot shell and in U-Boot env scripts, using 'fdt' command .
>>
>
> To make sure I understand the preferred architecture: are you suggesting that FW_LOADER is the preferred method, and that all the logic for finding, mounting, and reading from storage should be handled by board-specific scripts that parse the DT using fdt?
>
> My main objective with FS_LOADER was to provide a "zero-script" default for most common use case. While scripting is powerful, it seems beneficial to have a C-based driver that can natively read from a filesystem described by a standard DT binding, rather than requiring every board to script the same "find-and-mount" logic.
Maybe the scripts can be made common, similar to what distro bootcommand
did ?
The upside of doing the loading in a script is, that it allows users to
tweak the scripts without rebuilding and updating the bootloader, which
may be beneficial in case they need to load firmware from a device which
was not considered when the bootloader was built.
> Am I overlooking al drawback to that C-based approach, or perhaps missing some prior discussion on this?
See above.
--
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2025-11-02 14:25 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-31 15:21 [PATCH v4 0/5] net: phy: aquantia: Switch to generic firmware loader Beiyan Yun
2025-10-31 15:21 ` [PATCH v4 1/5] net: phy: aquantia: refresh format Beiyan Yun
2025-10-31 15:51 ` Marek Vasut
2025-10-31 17:21 ` Beiyan Yun
2025-10-31 18:33 ` Marek Vasut
2025-10-31 19:00 ` Tom Rini
2025-10-31 15:21 ` [PATCH v4 2/5] doc: bindings: use upstream bindings for aquantia phy Beiyan Yun
2025-10-31 15:53 ` Marek Vasut
2025-10-31 17:02 ` Beiyan Yun
2025-10-31 17:12 ` Marek Vasut
2025-10-31 15:21 ` [PATCH v4 3/5] net: phy: aquantia: replace the "mdi-reversal" node with "marvell, mdi-cfg-order" Beiyan Yun
2025-10-31 15:21 ` [PATCH v4 4/5] net: phy: aquantia: refactor firmware upload helpers Beiyan Yun
2025-10-31 15:21 ` [PATCH v4 5/5] net: phy: aquantia: use generic firmware loader Beiyan Yun
2025-10-31 15:41 ` Daniel Golle
2025-10-31 16:09 ` Beiyan Yun
2025-10-31 15:57 ` Marek Vasut
2025-10-31 16:34 ` Beiyan Yun
2025-10-31 16:51 ` Marek Vasut
2025-11-01 7:45 ` Beiyan Yun
2025-11-01 11:54 ` Marek Vasut
2025-11-02 4:57 ` Beiyan Yun
2025-11-02 14:25 ` Marek Vasut
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox