Re: fwnode_for_each_child_node() and OF backend discrepancy

From: Michael Walle
Date: Tue Jun 28 2022 - 09:48:10 EST


[adding Horatiu Vultur, because we now digress to the bug
in the switch, rather than that odd OF behavior]

Am 2022-06-28 15:29, schrieb Andy Shevchenko:
On Tue, Jun 28, 2022 at 3:23 PM Michael Walle <michael@xxxxxxxx> wrote:

>> I was trying to fix the lan966x driver [1] which doesn't work if there
>> are disabled nodes in between.
>
> Can you elaborate what's wrong now in the behaviour of the driver? In
> the code it uses twice the _available variant.

Imagine the following device tree snippet:
port0 {
reg = <0>;
status = "okay";
}
port1 {
reg = <1>;
status = "disabled";
}
port@2 {
reg = <2>;
status = "okay";
}

The driver will set num_phys_ports to 2. When port@2 is probed, it
will have the (correct!) physical port number 2. That will then
trigger various EINVAL checks with "port_num >= num_phys_ports" or
WARN()s.

It means the above mentioned condition is wrong: it should be

"port_idx >= num_phys_ports" (if the port_idx doesn't exists, that's
the bug in the first place)

I can't follow you here. Please note, that you need the actual
physical port number. It's not a made up number, but corresponds
to a physical port on that ethernet switch. So you can't just skip
the disabled ones. port@2 must have port number 2.

So the easiest fix would be to actual count all the child nodes
(regardless if they are available or not), assuming there are as
many nodes as physical ports.

But num_phys_ports being a property of the hardware

So, name is wrong, that's how I read it, it should be
num_of_acrive_phys_ports (or alike).

See above, it is not just an iterator but corresponds to
a hardware property.

I don't
think it's good to deduce it by counting the child nodes anyway,

Right.

but it should rather be a (hardcoded) property of the driver.

Also good to update.

Horatiu, can we determine the actual number of ports (or maybe
determine if its a LAN9668 or a LAN9662) from the hardware itself
in an easy way? That way we wouldn't need a new compatible string,
but could use the generic "lan966x" one.

-michael

[1] https://elixir.bootlin.com/linux/v5.19-rc4/source/drivers/net/ethernet/microchip/lan966x/lan966x_main.c