Re: [PATCH net-next v3 7/8] net: dsa: lantiq_gswip: store switch API version in priv

From: Daniel Golle
Date: Wed Aug 20 2025 - 19:57:48 EST


On Wed, Aug 20, 2025 at 02:55:49AM +0100, Daniel Golle wrote:
> Store the switch API version in struct gswip_priv (in host endian) to
> prepare supporting newer features such as 4096 VLANs and per-port
> configurable learning.
>
> Signed-off-by: Daniel Golle <daniel@xxxxxxxxxxxxxx>
> ---
> v3: use __force for version field endian exception (__le16 __force) to
> fix sparse warning.
> v2: no changes
>
> drivers/net/dsa/lantiq_gswip.c | 3 +++
> drivers/net/dsa/lantiq_gswip.h | 1 +
> 2 files changed, 4 insertions(+)
>
> diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
> index f8a43c351649..8999c3f2d290 100644
> --- a/drivers/net/dsa/lantiq_gswip.c
> +++ b/drivers/net/dsa/lantiq_gswip.c
> @@ -28,6 +28,7 @@
> #include "lantiq_gswip.h"
> #include "lantiq_pce.h"
>
> +#include <linux/byteorder/generic.h>
> #include <linux/delay.h>
> #include <linux/etherdevice.h>
> #include <linux/firmware.h>
> @@ -1936,6 +1937,8 @@ static int gswip_probe(struct platform_device *pdev)
> "gphy fw probe failed\n");
> }
>
> + priv->version = le16_to_cpu((__le16 __force)version);

I've researched this a bit more and came to the conclusion that while the
above works fine because all Lantiq SoCs with built-in switch are
big-endian machines it is still wrong.
I base this conclusion on the fact that when dealing with more recent
MDIO-connected switches (MaxLinear GSW1xx series) the host endian doesn't
play a role in the driver -- when dealing with 16-bit values on the MDIO
bus, the bus abstraction takes care of converting from/to host endianess.

The above statement will turn into a no-op on little-endian machines
(lets ignore the truncation to 16-bit for now). However, also on little-
endian machine the 'version' field is byte-swapped.

Hence I believe my original approach (using swab16) is better in my
opinion because rather than delcaring a specific endian, what needs to be
expressed is simply that this field is in opposite byte order than all the
other fields.

Hence I believe this should simply be a swab16() which will always result
in the version being in the right byte order to use comparative operators
in a meaningful way.

Sorry for the confusion.

> +
> /* bring up the mdio bus */
> err = gswip_mdio(priv);
> if (err) {
> diff --git a/drivers/net/dsa/lantiq_gswip.h b/drivers/net/dsa/lantiq_gswip.h
> index 0b7b6db4eab9..077d1928149b 100644
> --- a/drivers/net/dsa/lantiq_gswip.h
> +++ b/drivers/net/dsa/lantiq_gswip.h
> @@ -258,6 +258,7 @@ struct gswip_priv {
> struct gswip_gphy_fw *gphy_fw;
> u32 port_vlan_filter;
> struct mutex pce_table_lock;
> + u16 version;
> };
>
> #endif /* __LANTIQ_GSWIP_H */
> --
> 2.50.1
>