Commit 8a7576d2 authored by Daniel Golle's avatar Daniel Golle Committed by Jakub Kicinski
Browse files

net: dsa: lantiq_gswip: store switch API version in priv



Store the switch API version in struct gswip_priv. As the hardware has
the 'major/minor' version bytes in the wrong order preventing numerical
comparisons the version to be stored in gswip_priv is constructed in
such a way that the REV field is the most significant byte and the MOD
field the least significant byte. Also provide a conveniance macro to
allow comparing the stored version of the hardware against the already
defined GSWIP_VERSION_* macros.

This is done in order to prepare supporting newer features such as 4096
VLANs and per-port configurable learning which are only available
starting from specific hardware versions.

Signed-off-by: default avatarDaniel Golle <daniel@makrotopia.org>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/eddb51ae8d0b2046ca91906e93daad7be5af56d7.1755878232.git.daniel@makrotopia.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 1ccc4072
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -1907,6 +1907,16 @@ static int gswip_probe(struct platform_device *pdev)
	mutex_init(&priv->pce_table_lock);
	version = gswip_switch_r(priv, GSWIP_VERSION);

	/* The hardware has the 'major/minor' version bytes in the wrong order
	 * preventing numerical comparisons. Construct a 16-bit unsigned integer
	 * having the REV field as most significant byte and the MOD field as
	 * least significant byte. This is effectively swapping the two bytes of
	 * the version variable, but other than using swab16 it doesn't affect
	 * the source variable.
	 */
	priv->version = GSWIP_VERSION_REV(version) << 8 |
			GSWIP_VERSION_MOD(version);

	np = dev->of_node;
	switch (version) {
	case GSWIP_VERSION_2_0:
@@ -1955,8 +1965,7 @@ static int gswip_probe(struct platform_device *pdev)
	platform_set_drvdata(pdev, priv);

	dev_info(dev, "probed GSWIP version %lx mod %lx\n",
		 (version & GSWIP_VERSION_REV_MASK) >> GSWIP_VERSION_REV_SHIFT,
		 (version & GSWIP_VERSION_MOD_MASK) >> GSWIP_VERSION_MOD_SHIFT);
		 GSWIP_VERSION_REV(version), GSWIP_VERSION_MOD(version));
	return 0;

disable_switch:
+11 −2
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/swab.h>
#include <net/dsa.h>

/* GSWIP MDIO Registers */
@@ -85,14 +86,21 @@
#define  GSWIP_SWRES_R1			BIT(1)	/* GSWIP Software reset */
#define  GSWIP_SWRES_R0			BIT(0)	/* GSWIP Hardware reset */
#define GSWIP_VERSION			0x013
#define  GSWIP_VERSION_REV_SHIFT	0
#define  GSWIP_VERSION_REV_MASK		GENMASK(7, 0)
#define  GSWIP_VERSION_MOD_SHIFT	8
#define  GSWIP_VERSION_MOD_MASK		GENMASK(15, 8)
#define  GSWIP_VERSION_REV(v)		FIELD_GET(GSWIP_VERSION_REV_MASK, v)
#define  GSWIP_VERSION_MOD(v)		FIELD_GET(GSWIP_VERSION_MOD_MASK, v)
#define   GSWIP_VERSION_2_0		0x100
#define   GSWIP_VERSION_2_1		0x021
#define   GSWIP_VERSION_2_2		0x122
#define   GSWIP_VERSION_2_2_ETC		0x022
/* The hardware has the 'major/minor' version bytes in the wrong order
 * preventing numerical comparisons. Swap the bytes of the 16-bit value
 * to end up with REV being the most significant byte and MOD being the
 * least significant byte, which then allows comparing it with the
 * value stored in struct gswip_priv.
 */
#define GSWIP_VERSION_GE(priv, ver)	((priv)->version >= swab16(ver))

#define GSWIP_BM_RAM_VAL(x)		(0x043 - (x))
#define GSWIP_BM_RAM_ADDR		0x044
@@ -258,6 +266,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 */