[PATCH v2 net 4/4] net: ti: icssg-prueth-sr1: Fix port scan issues in prueth_probe()

From: Xiangwu Lai

Date: Tue Nov 10 2026 - 01:53:41 EST


The port scan loop in prueth_probe() has several issues:

- When reading the reg property of a port fails, the error is only
logged and the uninitialized value of reg is then used to decide
which slot the port node is stored in.

- of_node_get() is called on every port child before the reg value is
validated. If reg is neither 0 nor 1, the reference is never
released. If two ports use the same reg value, the second
assignment overwrites the first pointer and its reference is lost.

- The "port0 and port1 can't have same reg" check after the loop is
dead code: both variables are initialized to NULL, each iteration
assigns at most one of them, for_each_child_of_node() visits each
child exactly once, and the both-NULL case is handled by the
preceding check.

Fix the first issue by skipping a port when its reg property cannot
be read, and the second by taking the reference only when a port is
actually accepted. Reject duplicate reg values, which is what the
existing check intended but never caught, and remove the unreachable
check.

Fixes: e654b85a693e ("net: ti: icssg-prueth: Add ICSSG Ethernet driver for AM65x SR1.0 platforms")
Signed-off-by: Xiangwu Lai <laixiangwu@xxxxxxxxxxxxxxxxxxxx>
---
.../net/ethernet/ti/icssg/icssg_prueth_sr1.c | 26 +++++++++++--------
1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c
index ef1dc32ff..1a9dd70b2 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c
@@ -922,24 +922,34 @@ static int prueth_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(dev, "%pOF error reading port_id %d\n",
eth_node, ret);
+ continue;
}

- of_node_get(eth_node);
+ if (reg != 0 && reg != 1) {
+ dev_err(dev, "port reg should be 0 or 1\n");
+ continue;
+ }
+
+ if ((reg == 0 && eth0_node) || (reg == 1 && eth1_node)) {
+ dev_err(dev, "port reg %d already in use\n", reg);
+ ret = -ENODEV;
+ of_node_put(eth_node);
+ of_node_put(eth_ports_node);
+ goto put_cores;
+ }

if (reg == 0) {
- eth0_node = eth_node;
+ eth0_node = of_node_get(eth_node);
if (!of_device_is_available(eth0_node)) {
of_node_put(eth0_node);
eth0_node = NULL;
}
} else if (reg == 1) {
- eth1_node = eth_node;
+ eth1_node = of_node_get(eth_node);
if (!of_device_is_available(eth1_node)) {
of_node_put(eth1_node);
eth1_node = NULL;
}
- } else {
- dev_err(dev, "port reg should be 0 or 1\n");
}
}

@@ -951,12 +961,6 @@ static int prueth_probe(struct platform_device *pdev)
return -ENODEV;
}

- if (eth0_node == eth1_node) {
- dev_err(dev, "port0 and port1 can't have same reg\n");
- of_node_put(eth0_node);
- return -ENODEV;
- }
-
prueth->eth_node[PRUETH_MAC0] = eth0_node;
prueth->eth_node[PRUETH_MAC1] = eth1_node;

--
2.50.1.windows.1