[U-Boot, v1, 1/1] net: phy: air_en8811h: load the PHY firmware from filesystem on block device instead

Lucien.Jheng lucienzx159 at gmail.com
Sun Apr 20 05:10:47 CEST 2025


Deal maintainers

Considering system-level factors, this commit will not be submitted at 
this time.

Thank you.

Lucien.Jheng 於 2025/4/19 下午 05:43 寫道:
> Locating the AIROHA FW within the filesystem at the designated partition
> and path will trigger its automatic loading and writing to the PHY via MDIO.
>
> Signed-off-by: Lucien.Jheng <lucienzx159 at gmail.com>
> ---
>   drivers/net/phy/Kconfig       | 39 ++++++++------
>   drivers/net/phy/air_en8811h.c | 97 +++++++++++++++++++----------------
>   2 files changed, 78 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index 5b4cf30b0a3..384cef845e1 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -94,24 +94,33 @@ choice
>   	depends on PHY_AIROHA_EN8811H
>
>   config PHY_AIROHA_FW_IN_MMC
> -	bool "Airoha firmware in MMC boot1 partition"
> -
> -endchoice
> +	bool "Airoha firmware in MMC partition"
> +	help
> +		Airoha PHYs use firmware which can be loaded automatically
> +		from storage directly attached to the PHY, and then loaded
> +		via MDIO commands by the boot loader. The firmware is loaded
> +		from a file specified by the PHY_AIROHA_FW_PART,
> +		PHY_AIROHA_FW_DM_FILEPATH and PHY_AIROHA_FW_DSP_FILEPATH options.
> +
> +config PHY_AIROHA_FW_PART
> +	string "Airoha firmware partition"
> +	depends on PHY_AIROHA_FW_IN_MMC
> +	help
> +		Partition containing the firmware file.
>
> -config AIROHA_FW_ADDR
> -	hex "Airoha Firmware Address"
> -	depends on PHY_AIROHA_EN8811H
> -	default 0x0
> +config PHY_AIROHA_FW_DM_FILEPATH
> +	string "Airoha firmware DM file path in the filesystem"
> +	depends on PHY_AIROHA_FW_IN_MMC
> +	help
> +		Specify Airoha firmware DM file path in the filesystem.
>
> -config AIROHA_MD32_DM_SIZE
> -	hex "Airoha Firmware MD32 DM Size"
> -	depends on PHY_AIROHA_EN8811H
> -	default 0x4000
> +config PHY_AIROHA_FW_DSP_FILEPATH
> +	string "Airoha firmware DSP file path in the filesystem"
> +	depends on PHY_AIROHA_FW_IN_MMC
> +	help
> +		Specify Airoha firmware DSP file path in the filesystem.
>
> -config AIROHA_MD32_DSP_SIZE
> -	hex "Airoha Firmware MD32 DSP Size"
> -	depends on PHY_AIROHA_EN8811H
> -	default 0x20000
> +endchoice
>
>   menuconfig PHY_AQUANTIA
>   	bool "Aquantia Ethernet PHYs support"
> diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c
> index 96bb24418a0..8a2a25a8c74 100644
> --- a/drivers/net/phy/air_en8811h.c
> +++ b/drivers/net/phy/air_en8811h.c
> @@ -12,12 +12,14 @@
>    */
>   #include <phy.h>
>   #include <errno.h>
> +#include <log.h>
>   #include <malloc.h>
> +#include <fs.h>
>   #include <asm/unaligned.h>
>   #include <linux/iopoll.h>
> -#include <dm/device_compat.h>
>   #include <linux/bitops.h>
> -#include <mmc.h>
> +#include <dm/device_compat.h>
> +#include <u-boot/crc.h>
>
>   #define EN8811H_PHY_ID		0x03a2a411
>
> @@ -415,11 +417,6 @@ restore_page:
>   	return air_phy_restore_page(phydev, saved_page, ret);
>   }
>
> -__weak ulong *en8811h_get_fw_addr(void)
> -{
> -	return (ulong *)CONFIG_AIROHA_FW_ADDR;
> -}
> -
>   static int en8811h_wait_mcu_ready(struct phy_device *phydev)
>   {
>   	int ret, reg_value;
> @@ -437,85 +434,99 @@ static int en8811h_wait_mcu_ready(struct phy_device *phydev)
>   	return 0;
>   }
>
> +static void crc32_check(unsigned char *name, unsigned char *buf, u32 len)
> +{
> +	u32 ca_crc32;
> +
> +	ca_crc32 = crc32(0, buf, len);
> +	debug("%s: crc32 is 0x%x\n", name, ca_crc32);
> +}
> +
>   static int en8811h_load_firmware(struct phy_device *phydev)
>   {
>   	int ret;
> -	char *addr = NULL;
> +	void *addr = NULL;
>   	struct en8811h_priv *priv = phydev->priv;
> -	int dev = CONFIG_SYS_MMC_ENV_DEV;
> -	u32 cnt = (CONFIG_AIROHA_MD32_DM_SIZE +
> -		   CONFIG_AIROHA_MD32_DSP_SIZE) / 512;
> -	ulong airoha_fw_addr = (ulong)en8811h_get_fw_addr();
> -	u32 blk = airoha_fw_addr / 512;
> -
> -	addr = malloc(CONFIG_AIROHA_MD32_DM_SIZE + CONFIG_AIROHA_MD32_DSP_SIZE);
> -	if (!addr) {
> -		puts("cannot allocated buffer for firmware.\n");
> -		return -ENOMEM;
> -	}
>
>   	if (IS_ENABLED(CONFIG_PHY_AIROHA_FW_IN_MMC)) {
> -		struct mmc *mmc = find_mmc_device(dev);
> +		loff_t read;
>
> -		if (!mmc) {
> -			puts("Failed to find MMC device for Airoha ucode\n");
> -			goto en8811h_load_firmware_out;
> +		addr = malloc(EN8811H_MD32_DM_SIZE +
> +			      EN8811H_MD32_DSP_SIZE);
> +		if (!addr) {
> +			puts("cannot allocated buffer for firmware.\n");
> +			return -ENOMEM;
>   		}
>
> -		printf("MMC read: dev # %u, block # %u, count %u ...\n",
> -		       dev, blk, cnt);
> +		debug("\nLoading Airoha FW from %s %s\n",
> +		      CONFIG_PHY_AIROHA_FW_PART,
> +		      CONFIG_PHY_AIROHA_FW_DM_FILEPATH);
> +		ret = fs_set_blk_dev("mmc", CONFIG_PHY_AIROHA_FW_PART, FS_TYPE_ANY);
> +		if (ret < 0)
> +			goto en8811h_load_firmware_out;
>
> -		if (mmc_init(mmc)) {
> -			puts("initializing MMC device failed.\n");
> +		ret = fs_read(CONFIG_PHY_AIROHA_FW_DM_FILEPATH,
> +			      (ulong)addr, 0, EN8811H_MD32_DM_SIZE, &read);
> +		if (ret < 0)
>   			goto en8811h_load_firmware_out;
> -		}
>
> -		ret = mmc_set_part_conf(mmc, 1, 2, 2);
> -		if (ret) {
> -			puts("cannot access eMMC boot1 hw partition.\n");
> +		/* Calculate the CRC32 */
> +		crc32_check(CONFIG_PHY_AIROHA_FW_DM_FILEPATH,
> +			    (unsigned char *)addr, EN8811H_MD32_DM_SIZE);
> +
> +		debug("Loading Airoha FW from %s %s\n",
> +		      CONFIG_PHY_AIROHA_FW_PART,
> +		      CONFIG_PHY_AIROHA_FW_DSP_FILEPATH);
> +		ret = fs_set_blk_dev("mmc", CONFIG_PHY_AIROHA_FW_PART, FS_TYPE_ANY);
> +		if (ret < 0)
>   			goto en8811h_load_firmware_out;
> -		}
>
> -		(void)blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
> +		ret = fs_read(CONFIG_PHY_AIROHA_FW_DSP_FILEPATH,
> +			      (ulong)addr + EN8811H_MD32_DM_SIZE,
> +			      0, EN8811H_MD32_DSP_SIZE, &read);
> +		if (ret < 0)
> +			goto en8811h_load_firmware_out;
>
> -		mmc_set_part_conf(mmc, 1, 1, 0);
> +		/* Calculate the CRC32 */
> +		crc32_check(CONFIG_PHY_AIROHA_FW_DSP_FILEPATH,
> +			    (unsigned char *)addr + EN8811H_MD32_DM_SIZE,
> +			    EN8811H_MD32_DSP_SIZE);
>
>   	} else {
>   		puts("EN8811H firmware loading not implemented");
> -		free(addr);
> -		addr = NULL;
>   		return -EOPNOTSUPP;
>   	}
>
>   	ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
>   				     EN8811H_FW_CTRL_1_START);
>   	if (ret < 0)
> -		return ret;
> +		goto en8811h_load_firmware_out;
>
>   	ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
>   				      EN8811H_FW_CTRL_2_LOADING,
>   				      EN8811H_FW_CTRL_2_LOADING);
>   	if (ret < 0)
> -		return ret;
> +		goto en8811h_load_firmware_out;
>
> -	ret = air_write_buf(phydev, AIR_FW_ADDR_DM, CONFIG_AIROHA_MD32_DM_SIZE, addr);
> +	ret = air_write_buf(phydev, AIR_FW_ADDR_DM, EN8811H_MD32_DM_SIZE,
> +			    (unsigned char *)addr);
>   	if (ret < 0)
>   		goto en8811h_load_firmware_out;
>
> -	ret = air_write_buf(phydev, AIR_FW_ADDR_DSP, CONFIG_AIROHA_MD32_DSP_SIZE,
> -			    addr + CONFIG_AIROHA_MD32_DM_SIZE);
> +	ret = air_write_buf(phydev, AIR_FW_ADDR_DSP, EN8811H_MD32_DSP_SIZE,
> +			    (unsigned char *)addr + EN8811H_MD32_DM_SIZE);
>   	if (ret < 0)
>   		goto en8811h_load_firmware_out;
>
>   	ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
>   				      EN8811H_FW_CTRL_2_LOADING, 0);
>   	if (ret < 0)
> -		return ret;
> +		goto en8811h_load_firmware_out;
>
>   	ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
>   				     EN8811H_FW_CTRL_1_FINISH);
>   	if (ret < 0)
> -		return ret;
> +		goto en8811h_load_firmware_out;
>
>   	ret = en8811h_wait_mcu_ready(phydev);
>
> --
> 2.34.1
>


More information about the U-Boot mailing list