]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: b44: register a fixed phy using fixed_phy_register_100fd if needed
authorHeiner Kallweit <hkallweit1@gmail.com>
Thu, 30 Oct 2025 21:44:35 +0000 (22:44 +0100)
committerJakub Kicinski <kuba@kernel.org>
Wed, 5 Nov 2025 02:46:13 +0000 (18:46 -0800)
In case of bcm47xx a fixed phy is used, which so far is created
by platform code, using fixed_phy_add(). This function has a number of
problems, therefore create a potentially needed fixed phy here, using
fixed_phy_register_100fd.

Due to lack of hardware, this is compile-tested only.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Link: https://patch.msgid.link/53e4e74d-a49e-4f37-b970-5543a35041db@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/Kconfig
drivers/net/ethernet/broadcom/b44.c

index 9fdef874f5ca3300172c3f0a6d70b5c8adf8f0a5..666522d6477517cd49b87794155cb6f0b7f8547c 100644 (file)
@@ -25,6 +25,7 @@ config B44
        select SSB
        select MII
        select PHYLIB
+       select FIXED_PHY if BCM47XX
        help
          If you have a network (Ethernet) controller of this type, say Y
          or M here.
index 0353359c3fe96c3cd8cfd0095b9680190a237d85..888f28f11406fb02bd297a30d5537e53d12fe9e4 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/ssb/ssb.h>
 #include <linux/slab.h>
 #include <linux/phy.h>
+#include <linux/phy_fixed.h>
 
 #include <linux/uaccess.h>
 #include <asm/io.h>
@@ -2233,7 +2234,6 @@ static int b44_register_phy_one(struct b44 *bp)
        struct mii_bus *mii_bus;
        struct ssb_device *sdev = bp->sdev;
        struct phy_device *phydev;
-       char bus_id[MII_BUS_ID_SIZE + 3];
        struct ssb_sprom *sprom = &sdev->bus->sprom;
        int err;
 
@@ -2260,27 +2260,26 @@ static int b44_register_phy_one(struct b44 *bp)
                goto err_out_mdiobus;
        }
 
-       if (!mdiobus_is_registered_device(bp->mii_bus, bp->phy_addr) &&
-           (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) {
-
+       phydev = mdiobus_get_phy(bp->mii_bus, bp->phy_addr);
+       if (!phydev &&
+           sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM)) {
                dev_info(sdev->dev,
                         "could not find PHY at %i, use fixed one\n",
                         bp->phy_addr);
 
-               bp->phy_addr = 0;
-               snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, "fixed-0",
-                        bp->phy_addr);
-       } else {
-               snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id,
-                        bp->phy_addr);
+               phydev = fixed_phy_register_100fd();
+               if (!IS_ERR(phydev))
+                       bp->phy_addr = phydev->mdio.addr;
        }
 
-       phydev = phy_connect(bp->dev, bus_id, &b44_adjust_link,
-                            PHY_INTERFACE_MODE_MII);
-       if (IS_ERR(phydev)) {
+       if (IS_ERR_OR_NULL(phydev))
+               err = -ENODEV;
+       else
+               err = phy_connect_direct(bp->dev, phydev, &b44_adjust_link,
+                                        PHY_INTERFACE_MODE_MII);
+       if (err) {
                dev_err(sdev->dev, "could not attach PHY at %i\n",
                        bp->phy_addr);
-               err = PTR_ERR(phydev);
                goto err_out_mdiobus_unregister;
        }
 
@@ -2293,7 +2292,6 @@ static int b44_register_phy_one(struct b44 *bp)
        linkmode_copy(phydev->advertising, phydev->supported);
 
        bp->old_link = 0;
-       bp->phy_addr = phydev->mdio.addr;
 
        phy_attached_info(phydev);
 
@@ -2311,10 +2309,15 @@ err_out:
 
 static void b44_unregister_phy_one(struct b44 *bp)
 {
-       struct net_device *dev = bp->dev;
        struct mii_bus *mii_bus = bp->mii_bus;
+       struct net_device *dev = bp->dev;
+       struct phy_device *phydev;
+
+       phydev = dev->phydev;
 
-       phy_disconnect(dev->phydev);
+       phy_disconnect(phydev);
+       if (phy_is_pseudo_fixed_link(phydev))
+               fixed_phy_unregister(phydev);
        mdiobus_unregister(mii_bus);
        mdiobus_free(mii_bus);
 }