net: phy: Iterate over both registered PHYs and struct phy_driver linker list
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Sun, 19 Mar 2023 17:02:42 +0000 (18:02 +0100)
committerMarek Vasut <marek.vasut+renesas@mailbox.org>
Fri, 7 Apr 2023 12:18:48 +0000 (14:18 +0200)
Introduce U_BOOT_PHY_DRIVER() macro which is used to add struct phy_driver
into a new linker list section containing all compiled in struct phy_driver
drivers. This is so far empty until PHY drivers are converted over to this
macro.

Iterate over both drivers registered using soon to be legacy phy_register()
as well as drivers in the new linker list when looking up a suitable PHY
driver. This way, PHY drivers can be converted over to the new macro one
driver at a time.

The relocation of callbacks for linker list based drivers now happens in
phy_init() call as the drivers are available at that point in time, and
phy_register() is not called for those drivers.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Acked-by: Michal Simek <michal.simek@amd.com>
Tested-by: Michal Simek <michal.simek@amd.com> #microblaze (MANUAL_RELOC)
drivers/net/phy/phy.c
include/phy.h

index 5097c32..50bfabb 100644 (file)
@@ -495,6 +495,9 @@ static void phy_drv_reloc(struct phy_driver *drv)
 int phy_init(void)
 {
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
+       const int ll_n_ents = ll_entry_count(struct phy_driver, phy_driver);
+       struct phy_driver *drv, *ll_entry;
+
        /*
         * The pointers inside phy_drivers also needs to be updated incase of
         * manual reloc, without which these points to some invalid
@@ -504,6 +507,11 @@ int phy_init(void)
 
        head->next = (void *)head->next + gd->reloc_off;
        head->prev = (void *)head->prev + gd->reloc_off;
+
+       /* Perform manual relocation on linker list based PHY drivers */
+       ll_entry = ll_entry_start(struct phy_driver, phy_driver);
+       for (drv = ll_entry; drv != ll_entry + ll_n_ents; drv++)
+               phy_drv_reloc(drv);
 #endif
 
 #ifdef CONFIG_B53_SWITCH
@@ -660,6 +668,8 @@ static struct phy_driver *generic_for_phy(struct phy_device *phydev)
 
 static struct phy_driver *get_phy_driver(struct phy_device *phydev)
 {
+       const int ll_n_ents = ll_entry_count(struct phy_driver, phy_driver);
+       struct phy_driver *ll_entry;
        struct list_head *entry;
        int phy_id = phydev->phy_id;
        struct phy_driver *drv = NULL;
@@ -670,6 +680,11 @@ static struct phy_driver *get_phy_driver(struct phy_device *phydev)
                        return drv;
        }
 
+       ll_entry = ll_entry_start(struct phy_driver, phy_driver);
+       for (drv = ll_entry; drv != ll_entry + ll_n_ents; drv++)
+               if ((drv->uid & drv->mask) == (phy_id & drv->mask))
+                       return drv;
+
        /* If we made it here, there's no driver for this PHY */
        return generic_for_phy(phydev);
 }
index 87aa86c..1eccfac 100644 (file)
@@ -345,6 +345,13 @@ int phy_fixed_init(void);
 int phy_ncsi_init(void);
 int phy_xilinx_gmii2rgmii_init(void);
 
+/**
+ * U_BOOT_PHY_DRIVER() - Declare a new U-Boot driver
+ * @__name: name of the driver
+ */
+#define U_BOOT_PHY_DRIVER(__name)                                      \
+       ll_entry_declare(struct phy_driver, __name, phy_driver)
+
 int board_phy_config(struct phy_device *phydev);
 int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id);