Skip to content

Commit 385ef48

Browse files
Ansueldavem330
authored andcommitted
net: phy: add support for scanning PHY in PHY packages nodes
Add support for scanning PHY in PHY package nodes. PHY packages nodes are just container for actual PHY on the MDIO bus. Their PHY address defined in the PHY package node are absolute and reflect the address on the MDIO bus. mdio_bus.c and of_mdio.c is updated to now support and parse also PHY package subnode by checking if the node name match "ethernet-phy-package". As PHY package reg is mandatory and each PHY in the PHY package must have a reg, every invalid PHY Package node is ignored and will be skipped by the autoscan fallback. Signed-off-by: Christian Marangi <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8453c88 commit 385ef48

File tree

2 files changed

+92
-31
lines changed

2 files changed

+92
-31
lines changed

drivers/net/mdio/of_mdio.c

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,53 @@ bool of_mdiobus_child_is_phy(struct device_node *child)
139139
}
140140
EXPORT_SYMBOL(of_mdiobus_child_is_phy);
141141

142+
static int __of_mdiobus_parse_phys(struct mii_bus *mdio, struct device_node *np,
143+
bool *scanphys)
144+
{
145+
struct device_node *child;
146+
int addr, rc = 0;
147+
148+
/* Loop over the child nodes and register a phy_device for each phy */
149+
for_each_available_child_of_node(np, child) {
150+
if (of_node_name_eq(child, "ethernet-phy-package")) {
151+
/* Ignore invalid ethernet-phy-package node */
152+
if (!of_property_present(child, "reg"))
153+
continue;
154+
155+
rc = __of_mdiobus_parse_phys(mdio, child, NULL);
156+
if (rc && rc != -ENODEV)
157+
goto exit;
158+
159+
continue;
160+
}
161+
162+
addr = of_mdio_parse_addr(&mdio->dev, child);
163+
if (addr < 0) {
164+
/* Skip scanning for invalid ethernet-phy-package node */
165+
if (scanphys)
166+
*scanphys = true;
167+
continue;
168+
}
169+
170+
if (of_mdiobus_child_is_phy(child))
171+
rc = of_mdiobus_register_phy(mdio, child, addr);
172+
else
173+
rc = of_mdiobus_register_device(mdio, child, addr);
174+
175+
if (rc == -ENODEV)
176+
dev_err(&mdio->dev,
177+
"MDIO device at address %d is missing.\n",
178+
addr);
179+
else if (rc)
180+
goto exit;
181+
}
182+
183+
return 0;
184+
exit:
185+
of_node_put(child);
186+
return rc;
187+
}
188+
142189
/**
143190
* __of_mdiobus_register - Register mii_bus and create PHYs from the device tree
144191
* @mdio: pointer to mii_bus structure
@@ -180,33 +227,18 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np,
180227
return rc;
181228

182229
/* Loop over the child nodes and register a phy_device for each phy */
183-
for_each_available_child_of_node(np, child) {
184-
addr = of_mdio_parse_addr(&mdio->dev, child);
185-
if (addr < 0) {
186-
scanphys = true;
187-
continue;
188-
}
189-
190-
if (of_mdiobus_child_is_phy(child))
191-
rc = of_mdiobus_register_phy(mdio, child, addr);
192-
else
193-
rc = of_mdiobus_register_device(mdio, child, addr);
194-
195-
if (rc == -ENODEV)
196-
dev_err(&mdio->dev,
197-
"MDIO device at address %d is missing.\n",
198-
addr);
199-
else if (rc)
200-
goto unregister;
201-
}
230+
rc = __of_mdiobus_parse_phys(mdio, np, &scanphys);
231+
if (rc)
232+
goto unregister;
202233

203234
if (!scanphys)
204235
return 0;
205236

206237
/* auto scan for PHYs with empty reg property */
207238
for_each_available_child_of_node(np, child) {
208-
/* Skip PHYs with reg property set */
209-
if (of_property_present(child, "reg"))
239+
/* Skip PHYs with reg property set or ethernet-phy-package node */
240+
if (of_property_present(child, "reg") ||
241+
of_node_name_eq(child, "ethernet-phy-package"))
210242
continue;
211243

212244
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
@@ -227,15 +259,16 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np,
227259
if (!rc)
228260
break;
229261
if (rc != -ENODEV)
230-
goto unregister;
262+
goto put_unregister;
231263
}
232264
}
233265
}
234266

235267
return 0;
236268

237-
unregister:
269+
put_unregister:
238270
of_node_put(child);
271+
unregister:
239272
mdiobus_unregister(mdio);
240273
return rc;
241274
}

drivers/net/phy/mdio_bus.c

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -459,19 +459,34 @@ EXPORT_SYMBOL(of_mdio_find_bus);
459459
* found, set the of_node pointer for the mdio device. This allows
460460
* auto-probed phy devices to be supplied with information passed in
461461
* via DT.
462+
* If a PHY package is found, PHY is searched also there.
462463
*/
463-
static void of_mdiobus_link_mdiodev(struct mii_bus *bus,
464-
struct mdio_device *mdiodev)
464+
static int of_mdiobus_find_phy(struct device *dev, struct mdio_device *mdiodev,
465+
struct device_node *np)
465466
{
466-
struct device *dev = &mdiodev->dev;
467467
struct device_node *child;
468468

469-
if (dev->of_node || !bus->dev.of_node)
470-
return;
471-
472-
for_each_available_child_of_node(bus->dev.of_node, child) {
469+
for_each_available_child_of_node(np, child) {
473470
int addr;
474471

472+
if (of_node_name_eq(child, "ethernet-phy-package")) {
473+
/* Validate PHY package reg presence */
474+
if (!of_property_present(child, "reg")) {
475+
of_node_put(child);
476+
return -EINVAL;
477+
}
478+
479+
if (!of_mdiobus_find_phy(dev, mdiodev, child)) {
480+
/* The refcount for the PHY package will be
481+
* incremented later when PHY join the Package.
482+
*/
483+
of_node_put(child);
484+
return 0;
485+
}
486+
487+
continue;
488+
}
489+
475490
addr = of_mdio_parse_addr(dev, child);
476491
if (addr < 0)
477492
continue;
@@ -481,9 +496,22 @@ static void of_mdiobus_link_mdiodev(struct mii_bus *bus,
481496
/* The refcount on "child" is passed to the mdio
482497
* device. Do _not_ use of_node_put(child) here.
483498
*/
484-
return;
499+
return 0;
485500
}
486501
}
502+
503+
return -ENODEV;
504+
}
505+
506+
static void of_mdiobus_link_mdiodev(struct mii_bus *bus,
507+
struct mdio_device *mdiodev)
508+
{
509+
struct device *dev = &mdiodev->dev;
510+
511+
if (dev->of_node || !bus->dev.of_node)
512+
return;
513+
514+
of_mdiobus_find_phy(dev, mdiodev, bus->dev.of_node);
487515
}
488516
#else /* !IS_ENABLED(CONFIG_OF_MDIO) */
489517
static inline void of_mdiobus_link_mdiodev(struct mii_bus *mdio,

0 commit comments

Comments
 (0)