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 <lucienzx...@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

Reply via email to