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

From: Xiangwu Lai

Date: Tue Nov 10 2026 - 01:45:13 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: 128d5874c082 ("net: ti: icssg-prueth: Add ICSSG ethernet driver")
Signed-off-by: Xiangwu Lai <laixiangwu@xxxxxxxxxxxxxxxxxxxx>
---
drivers/net/ethernet/ti/icssg/icssg_prueth.c | 26 +++++++++++---------
1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index 9b971d1df..c19a51174 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -2217,24 +2217,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");
}
}

@@ -2246,12 +2256,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