Message ID | 20230620-feature-c45-over-c22-v2-10-def0ab9ccee2@kernel.org (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net: phy: C45-over-C22 access | expand |
Context | Check | Description |
---|---|---|
netdev/series_format | success | Posting correctly formatted |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/fixes_present | success | Fixes tag not required for -next series |
netdev/header_inline | success | No static functions without inline keyword in header files |
netdev/build_32bit | fail | Errors and warnings before: 8 this patch: 12 |
netdev/cc_maintainers | success | CCed 8 of 8 maintainers |
netdev/build_clang | fail | Errors and warnings before: 8 this patch: 12 |
netdev/verify_signedoff | success | Signed-off-by tag matches author and committer |
netdev/deprecated_api | success | None detected |
netdev/check_selftest | success | No net selftest shell script |
netdev/verify_fixes | success | No Fixes tag |
netdev/build_allmodconfig_warn | fail | Errors and warnings before: 8 this patch: 12 |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 91 lines checked |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/source_inline | success | Was 0 now: 0 |
On Fri, Jun 23, 2023 at 12:29:19PM +0200, Michael Walle wrote: ... > @@ -178,24 +209,26 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, > if (rc) > return rc; > > - /* Loop over the child nodes and register a phy_device for each phy */ > + /* Loop over the child nodes, skipping C45 PHYs so we can scan for > + * broken C22 PHYs. The C45 PHYs will be registered afterwards. > + */ > for_each_available_child_of_node(np, child) { > - addr = of_mdio_parse_addr(&mdio->dev, child); > - if (addr < 0) { > - scanphys = true; > + if (of_mdiobus_child_is_c45_phy(child)) > continue; > - } > + rc = of_mdiobus_register_child(mdio, child, &scanphys); > + if (rc) > + goto unregister; > + } > > - if (of_mdiobus_child_is_phy(child)) > - rc = of_mdiobus_register_phy(mdio, child, addr); > - else > - rc = of_mdiobus_register_device(mdio, child, addr); > + /* Some C22 PHYs are broken with C45 transactions. */ > + mdiobus_scan_for_broken_c45_access(mdio); Hi Michael, Unfortunately this seems to cause a build fauilure for x86_64 allmodconfig. ERROR: modpost: "mdiobus_scan_for_broken_c45_access" [drivers/net/mdio/of_mdio.ko] undefined!
Hi Simon, Am 2023-06-23 22:48, schrieb Simon Horman: > On Fri, Jun 23, 2023 at 12:29:19PM +0200, Michael Walle wrote: > > ... > >> @@ -178,24 +209,26 @@ int __of_mdiobus_register(struct mii_bus *mdio, >> struct device_node *np, >> if (rc) >> return rc; >> >> - /* Loop over the child nodes and register a phy_device for each phy >> */ >> + /* Loop over the child nodes, skipping C45 PHYs so we can scan for >> + * broken C22 PHYs. The C45 PHYs will be registered afterwards. >> + */ >> for_each_available_child_of_node(np, child) { >> - addr = of_mdio_parse_addr(&mdio->dev, child); >> - if (addr < 0) { >> - scanphys = true; >> + if (of_mdiobus_child_is_c45_phy(child)) >> continue; >> - } >> + rc = of_mdiobus_register_child(mdio, child, &scanphys); >> + if (rc) >> + goto unregister; >> + } >> >> - if (of_mdiobus_child_is_phy(child)) >> - rc = of_mdiobus_register_phy(mdio, child, addr); >> - else >> - rc = of_mdiobus_register_device(mdio, child, addr); >> + /* Some C22 PHYs are broken with C45 transactions. */ >> + mdiobus_scan_for_broken_c45_access(mdio); > > Hi Michael, > > Unfortunately this seems to cause a build fauilure > for x86_64 allmodconfig. > > ERROR: modpost: "mdiobus_scan_for_broken_c45_access" > [drivers/net/mdio/of_mdio.ko] undefined! Oops, sorry. Seems I've forgot to export it. I guess it should be EXPORT_SYMBOL_GPL(). -michael
diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c index 7eb32ebb846d..e9d3cf6b68ee 100644 --- a/drivers/net/mdio/of_mdio.c +++ b/drivers/net/mdio/of_mdio.c @@ -100,6 +100,11 @@ static const struct of_device_id whitelist_phys[] = { {} }; +static bool of_mdiobus_child_is_c45_phy(struct device_node *child) +{ + return of_device_is_compatible(child, "ethernet-phy-ieee802.3-c45"); +} + /* * Return true if the child node is for a phy. It must either: * o Compatible string of "ethernet-phy-idX.X" @@ -118,7 +123,7 @@ bool of_mdiobus_child_is_phy(struct device_node *child) if (of_get_phy_id(child, &phy_id) != -EINVAL) return true; - if (of_device_is_compatible(child, "ethernet-phy-ieee802.3-c45")) + if (of_mdiobus_child_is_c45_phy(child)) return true; if (of_device_is_compatible(child, "ethernet-phy-ieee802.3-c22")) @@ -138,6 +143,32 @@ bool of_mdiobus_child_is_phy(struct device_node *child) } EXPORT_SYMBOL(of_mdiobus_child_is_phy); +static int of_mdiobus_register_child(struct mii_bus *mdio, + struct device_node *child, bool *scanphys) +{ + int addr, rc; + + addr = of_mdio_parse_addr(&mdio->dev, child); + if (addr < 0) { + *scanphys = true; + return 0; + } + + if (mdiobus_is_registered_device(mdio, addr)) + return 0; + + if (of_mdiobus_child_is_phy(child)) + rc = of_mdiobus_register_phy(mdio, child, addr); + else + rc = of_mdiobus_register_device(mdio, child, addr); + + if (rc == -ENODEV) + dev_err(&mdio->dev, "MDIO device at address %d is missing.\n", + addr); + + return rc; +} + /** * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree * @mdio: pointer to mii_bus structure @@ -178,24 +209,26 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, if (rc) return rc; - /* Loop over the child nodes and register a phy_device for each phy */ + /* Loop over the child nodes, skipping C45 PHYs so we can scan for + * broken C22 PHYs. The C45 PHYs will be registered afterwards. + */ for_each_available_child_of_node(np, child) { - addr = of_mdio_parse_addr(&mdio->dev, child); - if (addr < 0) { - scanphys = true; + if (of_mdiobus_child_is_c45_phy(child)) continue; - } + rc = of_mdiobus_register_child(mdio, child, &scanphys); + if (rc) + goto unregister; + } - if (of_mdiobus_child_is_phy(child)) - rc = of_mdiobus_register_phy(mdio, child, addr); - else - rc = of_mdiobus_register_device(mdio, child, addr); + /* Some C22 PHYs are broken with C45 transactions. */ + mdiobus_scan_for_broken_c45_access(mdio); - if (rc == -ENODEV) - dev_err(&mdio->dev, - "MDIO device at address %d is missing.\n", - addr); - else if (rc) + /* Now add any missing C45 PHYs. If C45 access is not allowed, they + * will be registered with C45-over-C22 access. + */ + for_each_available_child_of_node(np, child) { + rc = of_mdiobus_register_child(mdio, child, &scanphys); + if (rc) goto unregister; }
Fall back to C45-over-C22 when the MDIO bus isn't capable of doing C45 transfers. This might be the case if there are broken PHYs on the bus or if the MDIO controller cannot do C45 transactions at all. For this to work, split the PHY registration into three steps, as done in the generic PHY probing code: (1) add C22 PHYs (2) scan for broken C22 PHYs (3) add C45 PHYs If step (2) detects a broken PHY, any PHYs will be added with C45-over-C22 access in step (3). Step (3) also ensures, that C45-over-C22 is used if C45 access is not supported at all on the bus. Signed-off-by: Michael Walle <mwalle@kernel.org> --- drivers/net/mdio/of_mdio.c | 63 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 15 deletions(-)