net: introduce helpers to get PHY ofnode from MAC
Add helpers ofnode_get_phy_node() and dev_get_phy_node() and use it in net/mdio-uclass.c function dm_eth_connect_phy_handle(). Also add corresponding UT test. This is useful because other part's of U-Boot may want to get PHY ofnode without connecting a PHY. Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
a7a96ef812
commit
f3dd213e15
@ -530,6 +530,13 @@
|
||||
fake-host-hwaddr = [00 00 66 44 22 22];
|
||||
};
|
||||
|
||||
phy_eth0: phy-test-eth {
|
||||
compatible = "sandbox,eth";
|
||||
reg = <0x10007000 0x1000>;
|
||||
fake-host-hwaddr = [00 00 66 44 22 77];
|
||||
phy-handle = <ðphy1>;
|
||||
};
|
||||
|
||||
dsa_eth0: dsa-test-eth {
|
||||
compatible = "sandbox,eth";
|
||||
reg = <0x10006000 0x1000>;
|
||||
@ -1555,6 +1562,12 @@
|
||||
|
||||
mdio: mdio-test {
|
||||
compatible = "sandbox,mdio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethphy1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
pm-bus-test {
|
||||
|
@ -1198,3 +1198,24 @@ const char *ofnode_conf_read_str(const char *prop_name)
|
||||
|
||||
return ofnode_read_string(node, prop_name);
|
||||
}
|
||||
|
||||
ofnode ofnode_get_phy_node(ofnode node)
|
||||
{
|
||||
/* DT node properties that reference a PHY node */
|
||||
static const char * const phy_handle_str[] = {
|
||||
"phy-handle", "phy", "phy-device",
|
||||
};
|
||||
struct ofnode_phandle_args args = {
|
||||
.node = ofnode_null()
|
||||
};
|
||||
int i;
|
||||
|
||||
assert(ofnode_valid(node));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(phy_handle_str); i++)
|
||||
if (!ofnode_parse_phandle_with_args(node, phy_handle_str[i],
|
||||
NULL, 0, 0, &args))
|
||||
break;
|
||||
|
||||
return args.node;
|
||||
}
|
||||
|
@ -398,3 +398,8 @@ int dev_decode_display_timing(const struct udevice *dev, int index,
|
||||
{
|
||||
return ofnode_decode_display_timing(dev_ofnode(dev), index, config);
|
||||
}
|
||||
|
||||
ofnode dev_get_phy_node(const struct udevice *dev)
|
||||
{
|
||||
return ofnode_get_phy_node(dev_ofnode(dev));
|
||||
}
|
||||
|
@ -1217,4 +1217,18 @@ int ofnode_conf_read_int(const char *prop_name, int default_val);
|
||||
*/
|
||||
const char *ofnode_conf_read_str(const char *prop_name);
|
||||
|
||||
/**
|
||||
* ofnode_get_phy_node() - Get PHY node for a MAC (if not fixed-link)
|
||||
*
|
||||
* This function parses PHY handle from the Ethernet controller's ofnode
|
||||
* (trying all possible PHY handle property names), and returns the PHY ofnode.
|
||||
*
|
||||
* Before this is used, ofnode_phy_is_fixed_link() should be checked first, and
|
||||
* if the result to that is true, this function should not be called.
|
||||
*
|
||||
* @eth_node: ofnode belonging to the Ethernet controller
|
||||
* Return: ofnode of the PHY, if it exists, otherwise an invalid ofnode
|
||||
*/
|
||||
ofnode ofnode_get_phy_node(ofnode eth_node);
|
||||
|
||||
#endif
|
||||
|
@ -743,6 +743,20 @@ int dev_read_pci_bus_range(const struct udevice *dev, struct resource *res);
|
||||
int dev_decode_display_timing(const struct udevice *dev, int index,
|
||||
struct display_timing *config);
|
||||
|
||||
/**
|
||||
* dev_get_phy_node() - Get PHY node for a MAC (if not fixed-link)
|
||||
*
|
||||
* This function parses PHY handle from the Ethernet controller's ofnode
|
||||
* (trying all possible PHY handle property names), and returns the PHY ofnode.
|
||||
*
|
||||
* Before this is used, ofnode_phy_is_fixed_link() should be checked first, and
|
||||
* if the result to that is true, this function should not be called.
|
||||
*
|
||||
* @dev: device representing the MAC
|
||||
* Return: ofnode of the PHY, if it exists, otherwise an invalid ofnode
|
||||
*/
|
||||
ofnode dev_get_phy_node(const struct udevice *dev);
|
||||
|
||||
#else /* CONFIG_DM_DEV_READ_INLINE is enabled */
|
||||
#include <asm/global_data.h>
|
||||
|
||||
@ -1092,6 +1106,11 @@ static inline int dev_decode_display_timing(const struct udevice *dev,
|
||||
return ofnode_decode_display_timing(dev_ofnode(dev), index, config);
|
||||
}
|
||||
|
||||
static inline ofnode dev_get_phy_node(const struct udevice *dev)
|
||||
{
|
||||
return ofnode_get_phy_node(dev_ofnode(dev));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DM_DEV_READ_INLINE */
|
||||
|
||||
/**
|
||||
|
@ -20,11 +20,6 @@ static const char * const phy_mode_str[] = {
|
||||
"phy-mode", "phy-connection-type"
|
||||
};
|
||||
|
||||
/* DT node properties that reference a PHY node */
|
||||
static const char * const phy_handle_str[] = {
|
||||
"phy-handle", "phy", "phy-device"
|
||||
};
|
||||
|
||||
void dm_mdio_probe_devices(void)
|
||||
{
|
||||
struct udevice *it;
|
||||
@ -137,23 +132,16 @@ static struct phy_device *dm_eth_connect_phy_handle(struct udevice *ethdev,
|
||||
u32 phy_addr;
|
||||
struct udevice *mdiodev;
|
||||
struct phy_device *phy;
|
||||
struct ofnode_phandle_args phandle = {.node = ofnode_null()};
|
||||
ofnode phynode;
|
||||
int i;
|
||||
|
||||
if (CONFIG_IS_ENABLED(PHY_FIXED) &&
|
||||
ofnode_phy_is_fixed_link(dev_ofnode(ethdev), &phynode)) {
|
||||
phy = phy_connect(NULL, 0, ethdev, interface);
|
||||
phandle.node = phynode;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(phy_handle_str); i++)
|
||||
if (!dev_read_phandle_with_args(ethdev, phy_handle_str[i], NULL,
|
||||
0, 0, &phandle))
|
||||
break;
|
||||
|
||||
if (!ofnode_valid(phandle.node)) {
|
||||
phynode = dev_get_phy_node(ethdev);
|
||||
if (!ofnode_valid(phynode)) {
|
||||
dev_dbg(ethdev, "can't find PHY node\n");
|
||||
return NULL;
|
||||
}
|
||||
@ -162,16 +150,16 @@ static struct phy_device *dm_eth_connect_phy_handle(struct udevice *ethdev,
|
||||
* reading 'reg' directly should be fine. This is a PHY node, the
|
||||
* address is always size 1 and requires no translation
|
||||
*/
|
||||
if (ofnode_read_u32(phandle.node, "reg", &phy_addr)) {
|
||||
if (ofnode_read_u32(phynode, "reg", &phy_addr)) {
|
||||
dev_dbg(ethdev, "missing reg property in phy node\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uclass_get_device_by_ofnode(UCLASS_MDIO,
|
||||
ofnode_get_parent(phandle.node),
|
||||
ofnode_get_parent(phynode),
|
||||
&mdiodev)) {
|
||||
dev_dbg(ethdev, "can't find MDIO bus for node %s\n",
|
||||
ofnode_get_name(ofnode_get_parent(phandle.node)));
|
||||
ofnode_get_name(ofnode_get_parent(phynode)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -179,7 +167,7 @@ static struct phy_device *dm_eth_connect_phy_handle(struct udevice *ethdev,
|
||||
|
||||
out:
|
||||
if (phy)
|
||||
phy->node = phandle.node;
|
||||
phy->node = phynode;
|
||||
|
||||
return phy;
|
||||
}
|
||||
|
@ -447,3 +447,21 @@ static int dm_test_ofnode_string_err(struct unit_test_state *uts)
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ofnode_string_err, UT_TESTF_LIVE_TREE);
|
||||
|
||||
static int dm_test_ofnode_get_phy(struct unit_test_state *uts)
|
||||
{
|
||||
ofnode eth_node, phy_node;
|
||||
u32 reg;
|
||||
|
||||
eth_node = ofnode_path("/phy-test-eth");
|
||||
ut_assert(ofnode_valid(eth_node));
|
||||
|
||||
phy_node = ofnode_get_phy_node(eth_node);
|
||||
ut_assert(ofnode_valid(phy_node));
|
||||
|
||||
reg = ofnode_read_u32_default(phy_node, "reg", -1U);
|
||||
ut_asserteq_64(0x1, reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ofnode_get_phy, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user