Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: b44: register a fixed phy using fixed_phy_register_100fd if needed

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>

authored by

Heiner Kallweit and committed by
Jakub Kicinski
10d2f15a 0ee21f39

+21 -17
+1
drivers/net/ethernet/broadcom/Kconfig
··· 25 25 select SSB 26 26 select MII 27 27 select PHYLIB 28 + select FIXED_PHY if BCM47XX 28 29 help 29 30 If you have a network (Ethernet) controller of this type, say Y 30 31 or M here.
+20 -17
drivers/net/ethernet/broadcom/b44.c
··· 31 31 #include <linux/ssb/ssb.h> 32 32 #include <linux/slab.h> 33 33 #include <linux/phy.h> 34 + #include <linux/phy_fixed.h> 34 35 35 36 #include <linux/uaccess.h> 36 37 #include <asm/io.h> ··· 2234 2233 struct mii_bus *mii_bus; 2235 2234 struct ssb_device *sdev = bp->sdev; 2236 2235 struct phy_device *phydev; 2237 - char bus_id[MII_BUS_ID_SIZE + 3]; 2238 2236 struct ssb_sprom *sprom = &sdev->bus->sprom; 2239 2237 int err; 2240 2238 ··· 2260 2260 goto err_out_mdiobus; 2261 2261 } 2262 2262 2263 - if (!mdiobus_is_registered_device(bp->mii_bus, bp->phy_addr) && 2264 - (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) { 2265 - 2263 + phydev = mdiobus_get_phy(bp->mii_bus, bp->phy_addr); 2264 + if (!phydev && 2265 + sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM)) { 2266 2266 dev_info(sdev->dev, 2267 2267 "could not find PHY at %i, use fixed one\n", 2268 2268 bp->phy_addr); 2269 2269 2270 - bp->phy_addr = 0; 2271 - snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, "fixed-0", 2272 - bp->phy_addr); 2273 - } else { 2274 - snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id, 2275 - bp->phy_addr); 2270 + phydev = fixed_phy_register_100fd(); 2271 + if (!IS_ERR(phydev)) 2272 + bp->phy_addr = phydev->mdio.addr; 2276 2273 } 2277 2274 2278 - phydev = phy_connect(bp->dev, bus_id, &b44_adjust_link, 2279 - PHY_INTERFACE_MODE_MII); 2280 - if (IS_ERR(phydev)) { 2275 + if (IS_ERR_OR_NULL(phydev)) 2276 + err = -ENODEV; 2277 + else 2278 + err = phy_connect_direct(bp->dev, phydev, &b44_adjust_link, 2279 + PHY_INTERFACE_MODE_MII); 2280 + if (err) { 2281 2281 dev_err(sdev->dev, "could not attach PHY at %i\n", 2282 2282 bp->phy_addr); 2283 - err = PTR_ERR(phydev); 2284 2283 goto err_out_mdiobus_unregister; 2285 2284 } 2286 2285 ··· 2292 2293 linkmode_copy(phydev->advertising, phydev->supported); 2293 2294 2294 2295 bp->old_link = 0; 2295 - bp->phy_addr = phydev->mdio.addr; 2296 2296 2297 2297 phy_attached_info(phydev); 2298 2298 ··· 2309 2311 2310 2312 static void b44_unregister_phy_one(struct b44 *bp) 2311 2313 { 2312 - struct net_device *dev = bp->dev; 2313 2314 struct mii_bus *mii_bus = bp->mii_bus; 2315 + struct net_device *dev = bp->dev; 2316 + struct phy_device *phydev; 2314 2317 2315 - phy_disconnect(dev->phydev); 2318 + phydev = dev->phydev; 2319 + 2320 + phy_disconnect(phydev); 2321 + if (phy_is_pseudo_fixed_link(phydev)) 2322 + fixed_phy_unregister(phydev); 2316 2323 mdiobus_unregister(mii_bus); 2317 2324 mdiobus_free(mii_bus); 2318 2325 }