* [PATCH net-next v3 0/8] net: dsa: lantiq_gswip: prepare for supporting new features
@ 2025-08-20 1:54 Daniel Golle
2025-08-20 1:54 ` [PATCH net-next v3 1/8] net: dsa: lantiq_gswip: deduplicate dsa_switch_ops Daniel Golle
` (7 more replies)
0 siblings, 8 replies; 13+ messages in thread
From: Daniel Golle @ 2025-08-20 1:54 UTC (permalink / raw)
To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Philipp Zabel,
Russell King, linux-kernel, netdev
Cc: Andreas Schirm, Lukas Stockmann, Alexander Sverdlin,
Peter Christen, Avinash Jayaraman, Bing tao Xu, Liang Xu,
Juraj Povazanec, Fanni (Fang-Yi) Chan, Benny (Ying-Tsan) Weng,
Livia M. Rosu, John Crispin
Prepare for supporting the newer standalone MaxLinear GSW1xx switch
family by refactoring the existing lantiq_gswip driver.
This is the first of a total of 3 series and doesn't yet introduce
any functional changes, but rather just makes the driver more
flexible, so new hardware and features can be supported in future.
This series has been preceded by an RFC series which covers everything
needed to support the MaxLinear GSW1xx family of switches. Andrew Lunn
had suggested to start with the 8 patches now submitted as they prepare
but don't yet introduce any functional changes.
Everything has been compile and runtime tested on AVM Fritz!Box 7490
(GSWIP version 2.1, VR9 v1.2)
Link: https://lore.kernel.org/netdev/aKDhFCNwjDDwRKsI@pidgin.makrotopia.org/
Daniel Golle (8):
net: dsa: lantiq_gswip: deduplicate dsa_switch_ops
net: dsa: lantiq_gswip: prepare for more CPU port options
net: dsa: lantiq_gswip: move definitions to header
net: dsa: lantiq_gswip: introduce bitmap for MII ports
net: dsa: lantiq_gswip: load model-specific microcode
net: dsa: lantiq_gswip: make DSA tag protocol model-specific
net: dsa: lantiq_gswip: store switch API version in priv
net: dsa: lantiq_gswip: add support for SWAPI version 2.3
drivers/net/dsa/lantiq_gswip.c | 404 ++++++++-------------------------
drivers/net/dsa/lantiq_gswip.h | 267 ++++++++++++++++++++++
drivers/net/dsa/lantiq_pce.h | 9 +-
3 files changed, 362 insertions(+), 318 deletions(-)
create mode 100644 drivers/net/dsa/lantiq_gswip.h
--
2.50.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH net-next v3 1/8] net: dsa: lantiq_gswip: deduplicate dsa_switch_ops
2025-08-20 1:54 [PATCH net-next v3 0/8] net: dsa: lantiq_gswip: prepare for supporting new features Daniel Golle
@ 2025-08-20 1:54 ` Daniel Golle
2025-08-20 1:54 ` [PATCH net-next v3 2/8] net: dsa: lantiq_gswip: prepare for more CPU port options Daniel Golle
` (6 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Daniel Golle @ 2025-08-20 1:54 UTC (permalink / raw)
To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Philipp Zabel,
Russell King, linux-kernel, netdev
Cc: Andreas Schirm, Lukas Stockmann, Alexander Sverdlin,
Peter Christen, Avinash Jayaraman, Bing tao Xu, Liang Xu,
Juraj Povazanec, Fanni (Fang-Yi) Chan, Benny (Ying-Tsan) Weng,
Livia M. Rosu, John Crispin
The two instances of struct dsa_switch_ops differ only by their
.phylink_get_caps op. Instead of having two instances of dsa_switch_ops,
rather just have a pointer to the phylink_get_caps function in
struct gswip_hw_info.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
---
v3: no changes
v2: no changes
drivers/net/dsa/lantiq_gswip.c | 44 ++++++++++++----------------------
1 file changed, 15 insertions(+), 29 deletions(-)
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index 6eb3140d4044..1cff938a87ef 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -254,7 +254,8 @@
struct gswip_hw_info {
int max_ports;
int cpu_port;
- const struct dsa_switch_ops *ops;
+ void (*phylink_get_caps)(struct dsa_switch *ds, int port,
+ struct phylink_config *config);
};
struct xway_gphy_match_data {
@@ -1554,6 +1555,14 @@ static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port,
MAC_10 | MAC_100 | MAC_1000;
}
+static void gswip_phylink_get_caps(struct dsa_switch *ds, int port,
+ struct phylink_config *config)
+{
+ struct gswip_priv *priv = ds->priv;
+
+ priv->hw_info->phylink_get_caps(ds, port, config);
+}
+
static void gswip_port_set_link(struct gswip_priv *priv, int port, bool link)
{
u32 mdio_phy;
@@ -1826,30 +1835,7 @@ static const struct phylink_mac_ops gswip_phylink_mac_ops = {
.mac_link_up = gswip_phylink_mac_link_up,
};
-static const struct dsa_switch_ops gswip_xrx200_switch_ops = {
- .get_tag_protocol = gswip_get_tag_protocol,
- .setup = gswip_setup,
- .port_enable = gswip_port_enable,
- .port_disable = gswip_port_disable,
- .port_bridge_join = gswip_port_bridge_join,
- .port_bridge_leave = gswip_port_bridge_leave,
- .port_fast_age = gswip_port_fast_age,
- .port_vlan_filtering = gswip_port_vlan_filtering,
- .port_vlan_add = gswip_port_vlan_add,
- .port_vlan_del = gswip_port_vlan_del,
- .port_stp_state_set = gswip_port_stp_state_set,
- .port_fdb_add = gswip_port_fdb_add,
- .port_fdb_del = gswip_port_fdb_del,
- .port_fdb_dump = gswip_port_fdb_dump,
- .port_change_mtu = gswip_port_change_mtu,
- .port_max_mtu = gswip_port_max_mtu,
- .phylink_get_caps = gswip_xrx200_phylink_get_caps,
- .get_strings = gswip_get_strings,
- .get_ethtool_stats = gswip_get_ethtool_stats,
- .get_sset_count = gswip_get_sset_count,
-};
-
-static const struct dsa_switch_ops gswip_xrx300_switch_ops = {
+static const struct dsa_switch_ops gswip_switch_ops = {
.get_tag_protocol = gswip_get_tag_protocol,
.setup = gswip_setup,
.port_enable = gswip_port_enable,
@@ -1866,7 +1852,7 @@ static const struct dsa_switch_ops gswip_xrx300_switch_ops = {
.port_fdb_dump = gswip_port_fdb_dump,
.port_change_mtu = gswip_port_change_mtu,
.port_max_mtu = gswip_port_max_mtu,
- .phylink_get_caps = gswip_xrx300_phylink_get_caps,
+ .phylink_get_caps = gswip_phylink_get_caps,
.get_strings = gswip_get_strings,
.get_ethtool_stats = gswip_get_ethtool_stats,
.get_sset_count = gswip_get_sset_count,
@@ -2129,7 +2115,7 @@ static int gswip_probe(struct platform_device *pdev)
priv->ds->dev = dev;
priv->ds->num_ports = priv->hw_info->max_ports;
priv->ds->priv = priv;
- priv->ds->ops = priv->hw_info->ops;
+ priv->ds->ops = &gswip_switch_ops;
priv->ds->phylink_mac_ops = &gswip_phylink_mac_ops;
priv->dev = dev;
mutex_init(&priv->pce_table_lock);
@@ -2230,13 +2216,13 @@ static void gswip_shutdown(struct platform_device *pdev)
static const struct gswip_hw_info gswip_xrx200 = {
.max_ports = 7,
.cpu_port = 6,
- .ops = &gswip_xrx200_switch_ops,
+ .phylink_get_caps = gswip_xrx200_phylink_get_caps,
};
static const struct gswip_hw_info gswip_xrx300 = {
.max_ports = 7,
.cpu_port = 6,
- .ops = &gswip_xrx300_switch_ops,
+ .phylink_get_caps = gswip_xrx300_phylink_get_caps,
};
static const struct of_device_id gswip_of_match[] = {
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v3 2/8] net: dsa: lantiq_gswip: prepare for more CPU port options
2025-08-20 1:54 [PATCH net-next v3 0/8] net: dsa: lantiq_gswip: prepare for supporting new features Daniel Golle
2025-08-20 1:54 ` [PATCH net-next v3 1/8] net: dsa: lantiq_gswip: deduplicate dsa_switch_ops Daniel Golle
@ 2025-08-20 1:54 ` Daniel Golle
2025-08-20 1:54 ` [PATCH net-next v3 3/8] net: dsa: lantiq_gswip: move definitions to header Daniel Golle
` (5 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Daniel Golle @ 2025-08-20 1:54 UTC (permalink / raw)
To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Philipp Zabel,
Russell King, linux-kernel, netdev
Cc: Andreas Schirm, Lukas Stockmann, Alexander Sverdlin,
Peter Christen, Avinash Jayaraman, Bing tao Xu, Liang Xu,
Juraj Povazanec, Fanni (Fang-Yi) Chan, Benny (Ying-Tsan) Weng,
Livia M. Rosu, John Crispin
The MaxLinear GSW1xx series of switches support using either the
(R)(G)MII interface on port 5 or the SGMII interface on port 4 to be
used as CPU port. Prepare for supporting them by defining a mask of
allowed CPU ports instead of a single port.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
---
v3: no changes
v2: no changes
drivers/net/dsa/lantiq_gswip.c | 79 +++++++++++++++++++++-------------
1 file changed, 50 insertions(+), 29 deletions(-)
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index 1cff938a87ef..a36b31f7d30b 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -253,7 +253,7 @@
struct gswip_hw_info {
int max_ports;
- int cpu_port;
+ unsigned int allowed_cpu_ports;
void (*phylink_get_caps)(struct dsa_switch *ds, int port,
struct phylink_config *config);
};
@@ -655,7 +655,6 @@ static int gswip_add_single_port_br(struct gswip_priv *priv, int port, bool add)
{
struct gswip_pce_table_entry vlan_active = {0,};
struct gswip_pce_table_entry vlan_mapping = {0,};
- unsigned int cpu_port = priv->hw_info->cpu_port;
int err;
vlan_active.index = port + 1;
@@ -675,7 +674,7 @@ static int gswip_add_single_port_br(struct gswip_priv *priv, int port, bool add)
vlan_mapping.index = port + 1;
vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING;
vlan_mapping.val[0] = 0 /* vid */;
- vlan_mapping.val[1] = BIT(port) | BIT(cpu_port);
+ vlan_mapping.val[1] = BIT(port) | dsa_cpu_ports(priv->ds);
vlan_mapping.val[2] = 0;
err = gswip_pce_table_entry_write(priv, &vlan_mapping);
if (err) {
@@ -805,10 +804,10 @@ static int gswip_port_vlan_filtering(struct dsa_switch *ds, int port,
static int gswip_setup(struct dsa_switch *ds)
{
+ unsigned int cpu_ports = dsa_cpu_ports(ds);
struct gswip_priv *priv = ds->priv;
- unsigned int cpu_port = priv->hw_info->cpu_port;
- int i;
- int err;
+ struct dsa_port *cpu_dp;
+ int err, i;
gswip_switch_w(priv, GSWIP_SWRES_R0, GSWIP_SWRES);
usleep_range(5000, 10000);
@@ -830,9 +829,9 @@ static int gswip_setup(struct dsa_switch *ds)
}
/* Default unknown Broadcast/Multicast/Unicast port maps */
- gswip_switch_w(priv, BIT(cpu_port), GSWIP_PCE_PMAP1);
- gswip_switch_w(priv, BIT(cpu_port), GSWIP_PCE_PMAP2);
- gswip_switch_w(priv, BIT(cpu_port), GSWIP_PCE_PMAP3);
+ gswip_switch_w(priv, cpu_ports, GSWIP_PCE_PMAP1);
+ gswip_switch_w(priv, cpu_ports, GSWIP_PCE_PMAP2);
+ gswip_switch_w(priv, cpu_ports, GSWIP_PCE_PMAP3);
/* Deactivate MDIO PHY auto polling. Some PHYs as the AR8030 have an
* interoperability problem with this auto polling mechanism because
@@ -861,13 +860,15 @@ static int gswip_setup(struct dsa_switch *ds)
GSWIP_MII_CFG_EN | GSWIP_MII_CFG_ISOLATE,
0, i);
- /* enable special tag insertion on cpu port */
- gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN,
- GSWIP_FDMA_PCTRLp(cpu_port));
+ dsa_switch_for_each_cpu_port(cpu_dp, ds) {
+ /* enable special tag insertion on cpu port */
+ gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN,
+ GSWIP_FDMA_PCTRLp(cpu_dp->index));
- /* accept special tag in ingress direction */
- gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_INGRESS,
- GSWIP_PCE_PCTRL_0p(cpu_port));
+ /* accept special tag in ingress direction */
+ gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_INGRESS,
+ GSWIP_PCE_PCTRL_0p(cpu_dp->index));
+ }
gswip_switch_mask(priv, 0, GSWIP_BM_QUEUE_GCTRL_GL_MOD,
GSWIP_BM_QUEUE_GCTRL);
@@ -963,7 +964,6 @@ static int gswip_vlan_add_unaware(struct gswip_priv *priv,
{
struct gswip_pce_table_entry vlan_mapping = {0,};
unsigned int max_ports = priv->hw_info->max_ports;
- unsigned int cpu_port = priv->hw_info->cpu_port;
bool active_vlan_created = false;
int idx = -1;
int i;
@@ -1003,7 +1003,7 @@ static int gswip_vlan_add_unaware(struct gswip_priv *priv,
}
/* Update the VLAN mapping entry and write it to the switch */
- vlan_mapping.val[1] |= BIT(cpu_port);
+ vlan_mapping.val[1] |= dsa_cpu_ports(priv->ds);
vlan_mapping.val[1] |= BIT(port);
err = gswip_pce_table_entry_write(priv, &vlan_mapping);
if (err) {
@@ -1025,7 +1025,7 @@ static int gswip_vlan_add_aware(struct gswip_priv *priv,
{
struct gswip_pce_table_entry vlan_mapping = {0,};
unsigned int max_ports = priv->hw_info->max_ports;
- unsigned int cpu_port = priv->hw_info->cpu_port;
+ unsigned int cpu_ports = dsa_cpu_ports(priv->ds);
bool active_vlan_created = false;
int idx = -1;
int fid = -1;
@@ -1072,8 +1072,8 @@ static int gswip_vlan_add_aware(struct gswip_priv *priv,
vlan_mapping.val[0] = vid;
/* Update the VLAN mapping entry and write it to the switch */
- vlan_mapping.val[1] |= BIT(cpu_port);
- vlan_mapping.val[2] |= BIT(cpu_port);
+ vlan_mapping.val[1] |= cpu_ports;
+ vlan_mapping.val[2] |= cpu_ports;
vlan_mapping.val[1] |= BIT(port);
if (untagged)
vlan_mapping.val[2] &= ~BIT(port);
@@ -1100,7 +1100,6 @@ static int gswip_vlan_remove(struct gswip_priv *priv,
{
struct gswip_pce_table_entry vlan_mapping = {0,};
unsigned int max_ports = priv->hw_info->max_ports;
- unsigned int cpu_port = priv->hw_info->cpu_port;
int idx = -1;
int i;
int err;
@@ -1136,7 +1135,7 @@ static int gswip_vlan_remove(struct gswip_priv *priv,
}
/* In case all ports are removed from the bridge, remove the VLAN */
- if ((vlan_mapping.val[1] & ~BIT(cpu_port)) == 0) {
+ if (!(vlan_mapping.val[1] & ~dsa_cpu_ports(priv->ds))) {
err = gswip_vlan_active_remove(priv, idx);
if (err) {
dev_err(priv->dev, "failed to write active VLAN: %d\n",
@@ -2079,6 +2078,30 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv,
return err;
}
+static int gswip_validate_cpu_port(struct dsa_switch *ds)
+{
+ struct gswip_priv *priv = ds->priv;
+ struct dsa_port *cpu_dp;
+ int cpu_port = -1;
+
+ dsa_switch_for_each_cpu_port(cpu_dp, ds) {
+ if (cpu_port != -1)
+ return dev_err_probe(ds->dev, -EINVAL,
+ "only a single CPU port is supported\n");
+
+ cpu_port = cpu_dp->index;
+ }
+
+ if (cpu_port == -1)
+ return dev_err_probe(ds->dev, -EINVAL, "no CPU port defined\n");
+
+ if (BIT(cpu_port) & ~priv->hw_info->allowed_cpu_ports)
+ return dev_err_probe(ds->dev, -EINVAL,
+ "unsupported CPU port defined\n");
+
+ return 0;
+}
+
static int gswip_probe(struct platform_device *pdev)
{
struct device_node *np, *gphy_fw_np;
@@ -2161,12 +2184,10 @@ static int gswip_probe(struct platform_device *pdev)
dev_err_probe(dev, err, "dsa switch registration failed\n");
goto gphy_fw_remove;
}
- if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) {
- err = dev_err_probe(dev, -EINVAL,
- "wrong CPU port defined, HW only supports port: %i\n",
- priv->hw_info->cpu_port);
+
+ err = gswip_validate_cpu_port(priv->ds);
+ if (err)
goto disable_switch;
- }
platform_set_drvdata(pdev, priv);
@@ -2215,13 +2236,13 @@ static void gswip_shutdown(struct platform_device *pdev)
static const struct gswip_hw_info gswip_xrx200 = {
.max_ports = 7,
- .cpu_port = 6,
+ .allowed_cpu_ports = BIT(6),
.phylink_get_caps = gswip_xrx200_phylink_get_caps,
};
static const struct gswip_hw_info gswip_xrx300 = {
.max_ports = 7,
- .cpu_port = 6,
+ .allowed_cpu_ports = BIT(6),
.phylink_get_caps = gswip_xrx300_phylink_get_caps,
};
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v3 3/8] net: dsa: lantiq_gswip: move definitions to header
2025-08-20 1:54 [PATCH net-next v3 0/8] net: dsa: lantiq_gswip: prepare for supporting new features Daniel Golle
2025-08-20 1:54 ` [PATCH net-next v3 1/8] net: dsa: lantiq_gswip: deduplicate dsa_switch_ops Daniel Golle
2025-08-20 1:54 ` [PATCH net-next v3 2/8] net: dsa: lantiq_gswip: prepare for more CPU port options Daniel Golle
@ 2025-08-20 1:54 ` Daniel Golle
2025-08-20 1:55 ` [PATCH net-next v3 4/8] net: dsa: lantiq_gswip: introduce bitmap for MII ports Daniel Golle
` (4 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Daniel Golle @ 2025-08-20 1:54 UTC (permalink / raw)
To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Philipp Zabel,
Russell King, linux-kernel, netdev
Cc: Andreas Schirm, Lukas Stockmann, Alexander Sverdlin,
Peter Christen, Avinash Jayaraman, Bing tao Xu, Liang Xu,
Juraj Povazanec, Fanni (Fang-Yi) Chan, Benny (Ying-Tsan) Weng,
Livia M. Rosu, John Crispin
Introduce header file and move register definitions as well as the
definitions struct gswip_hw_info and struct gswip_priv there.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
---
v3: remove accidentally added VAL1_VALID bit definition
v2: no changes
drivers/net/dsa/lantiq_gswip.c | 250 +-------------------------------
drivers/net/dsa/lantiq_gswip.h | 252 +++++++++++++++++++++++++++++++++
2 files changed, 255 insertions(+), 247 deletions(-)
create mode 100644 drivers/net/dsa/lantiq_gswip.h
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index a36b31f7d30b..b1b250fc4f61 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -25,7 +25,9 @@
* between all LAN ports by default.
*/
-#include <linux/clk.h>
+#include "lantiq_gswip.h"
+#include "lantiq_pce.h"
+
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
@@ -39,259 +41,13 @@
#include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/phylink.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-#include <linux/reset.h>
-#include <net/dsa.h>
#include <dt-bindings/mips/lantiq_rcu_gphy.h>
-#include "lantiq_pce.h"
-
-/* GSWIP MDIO Registers */
-#define GSWIP_MDIO_GLOB 0x00
-#define GSWIP_MDIO_GLOB_ENABLE BIT(15)
-#define GSWIP_MDIO_CTRL 0x08
-#define GSWIP_MDIO_CTRL_BUSY BIT(12)
-#define GSWIP_MDIO_CTRL_RD BIT(11)
-#define GSWIP_MDIO_CTRL_WR BIT(10)
-#define GSWIP_MDIO_CTRL_PHYAD_MASK 0x1f
-#define GSWIP_MDIO_CTRL_PHYAD_SHIFT 5
-#define GSWIP_MDIO_CTRL_REGAD_MASK 0x1f
-#define GSWIP_MDIO_READ 0x09
-#define GSWIP_MDIO_WRITE 0x0A
-#define GSWIP_MDIO_MDC_CFG0 0x0B
-#define GSWIP_MDIO_MDC_CFG1 0x0C
-#define GSWIP_MDIO_PHYp(p) (0x15 - (p))
-#define GSWIP_MDIO_PHY_LINK_MASK 0x6000
-#define GSWIP_MDIO_PHY_LINK_AUTO 0x0000
-#define GSWIP_MDIO_PHY_LINK_DOWN 0x4000
-#define GSWIP_MDIO_PHY_LINK_UP 0x2000
-#define GSWIP_MDIO_PHY_SPEED_MASK 0x1800
-#define GSWIP_MDIO_PHY_SPEED_AUTO 0x1800
-#define GSWIP_MDIO_PHY_SPEED_M10 0x0000
-#define GSWIP_MDIO_PHY_SPEED_M100 0x0800
-#define GSWIP_MDIO_PHY_SPEED_G1 0x1000
-#define GSWIP_MDIO_PHY_FDUP_MASK 0x0600
-#define GSWIP_MDIO_PHY_FDUP_AUTO 0x0000
-#define GSWIP_MDIO_PHY_FDUP_EN 0x0200
-#define GSWIP_MDIO_PHY_FDUP_DIS 0x0600
-#define GSWIP_MDIO_PHY_FCONTX_MASK 0x0180
-#define GSWIP_MDIO_PHY_FCONTX_AUTO 0x0000
-#define GSWIP_MDIO_PHY_FCONTX_EN 0x0100
-#define GSWIP_MDIO_PHY_FCONTX_DIS 0x0180
-#define GSWIP_MDIO_PHY_FCONRX_MASK 0x0060
-#define GSWIP_MDIO_PHY_FCONRX_AUTO 0x0000
-#define GSWIP_MDIO_PHY_FCONRX_EN 0x0020
-#define GSWIP_MDIO_PHY_FCONRX_DIS 0x0060
-#define GSWIP_MDIO_PHY_ADDR_MASK 0x001f
-#define GSWIP_MDIO_PHY_MASK (GSWIP_MDIO_PHY_ADDR_MASK | \
- GSWIP_MDIO_PHY_FCONRX_MASK | \
- GSWIP_MDIO_PHY_FCONTX_MASK | \
- GSWIP_MDIO_PHY_LINK_MASK | \
- GSWIP_MDIO_PHY_SPEED_MASK | \
- GSWIP_MDIO_PHY_FDUP_MASK)
-
-/* GSWIP MII Registers */
-#define GSWIP_MII_CFGp(p) (0x2 * (p))
-#define GSWIP_MII_CFG_RESET BIT(15)
-#define GSWIP_MII_CFG_EN BIT(14)
-#define GSWIP_MII_CFG_ISOLATE BIT(13)
-#define GSWIP_MII_CFG_LDCLKDIS BIT(12)
-#define GSWIP_MII_CFG_RGMII_IBS BIT(8)
-#define GSWIP_MII_CFG_RMII_CLK BIT(7)
-#define GSWIP_MII_CFG_MODE_MIIP 0x0
-#define GSWIP_MII_CFG_MODE_MIIM 0x1
-#define GSWIP_MII_CFG_MODE_RMIIP 0x2
-#define GSWIP_MII_CFG_MODE_RMIIM 0x3
-#define GSWIP_MII_CFG_MODE_RGMII 0x4
-#define GSWIP_MII_CFG_MODE_GMII 0x9
-#define GSWIP_MII_CFG_MODE_MASK 0xf
-#define GSWIP_MII_CFG_RATE_M2P5 0x00
-#define GSWIP_MII_CFG_RATE_M25 0x10
-#define GSWIP_MII_CFG_RATE_M125 0x20
-#define GSWIP_MII_CFG_RATE_M50 0x30
-#define GSWIP_MII_CFG_RATE_AUTO 0x40
-#define GSWIP_MII_CFG_RATE_MASK 0x70
-#define GSWIP_MII_PCDU0 0x01
-#define GSWIP_MII_PCDU1 0x03
-#define GSWIP_MII_PCDU5 0x05
-#define GSWIP_MII_PCDU_TXDLY_MASK GENMASK(2, 0)
-#define GSWIP_MII_PCDU_RXDLY_MASK GENMASK(9, 7)
-
-/* GSWIP Core Registers */
-#define GSWIP_SWRES 0x000
-#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_2_0 0x100
-#define GSWIP_VERSION_2_1 0x021
-#define GSWIP_VERSION_2_2 0x122
-#define GSWIP_VERSION_2_2_ETC 0x022
-
-#define GSWIP_BM_RAM_VAL(x) (0x043 - (x))
-#define GSWIP_BM_RAM_ADDR 0x044
-#define GSWIP_BM_RAM_CTRL 0x045
-#define GSWIP_BM_RAM_CTRL_BAS BIT(15)
-#define GSWIP_BM_RAM_CTRL_OPMOD BIT(5)
-#define GSWIP_BM_RAM_CTRL_ADDR_MASK GENMASK(4, 0)
-#define GSWIP_BM_QUEUE_GCTRL 0x04A
-#define GSWIP_BM_QUEUE_GCTRL_GL_MOD BIT(10)
-/* buffer management Port Configuration Register */
-#define GSWIP_BM_PCFGp(p) (0x080 + ((p) * 2))
-#define GSWIP_BM_PCFG_CNTEN BIT(0) /* RMON Counter Enable */
-#define GSWIP_BM_PCFG_IGCNT BIT(1) /* Ingres Special Tag RMON count */
-/* buffer management Port Control Register */
-#define GSWIP_BM_RMON_CTRLp(p) (0x81 + ((p) * 2))
-#define GSWIP_BM_CTRL_RMON_RAM1_RES BIT(0) /* Software Reset for RMON RAM 1 */
-#define GSWIP_BM_CTRL_RMON_RAM2_RES BIT(1) /* Software Reset for RMON RAM 2 */
-
-/* PCE */
-#define GSWIP_PCE_TBL_KEY(x) (0x447 - (x))
-#define GSWIP_PCE_TBL_MASK 0x448
-#define GSWIP_PCE_TBL_VAL(x) (0x44D - (x))
-#define GSWIP_PCE_TBL_ADDR 0x44E
-#define GSWIP_PCE_TBL_CTRL 0x44F
-#define GSWIP_PCE_TBL_CTRL_BAS BIT(15)
-#define GSWIP_PCE_TBL_CTRL_TYPE BIT(13)
-#define GSWIP_PCE_TBL_CTRL_VLD BIT(12)
-#define GSWIP_PCE_TBL_CTRL_KEYFORM BIT(11)
-#define GSWIP_PCE_TBL_CTRL_GMAP_MASK GENMASK(10, 7)
-#define GSWIP_PCE_TBL_CTRL_OPMOD_MASK GENMASK(6, 5)
-#define GSWIP_PCE_TBL_CTRL_OPMOD_ADRD 0x00
-#define GSWIP_PCE_TBL_CTRL_OPMOD_ADWR 0x20
-#define GSWIP_PCE_TBL_CTRL_OPMOD_KSRD 0x40
-#define GSWIP_PCE_TBL_CTRL_OPMOD_KSWR 0x60
-#define GSWIP_PCE_TBL_CTRL_ADDR_MASK GENMASK(4, 0)
-#define GSWIP_PCE_PMAP1 0x453 /* Monitoring port map */
-#define GSWIP_PCE_PMAP2 0x454 /* Default Multicast port map */
-#define GSWIP_PCE_PMAP3 0x455 /* Default Unknown Unicast port map */
-#define GSWIP_PCE_GCTRL_0 0x456
-#define GSWIP_PCE_GCTRL_0_MTFL BIT(0) /* MAC Table Flushing */
-#define GSWIP_PCE_GCTRL_0_MC_VALID BIT(3)
-#define GSWIP_PCE_GCTRL_0_VLAN BIT(14) /* VLAN aware Switching */
-#define GSWIP_PCE_GCTRL_1 0x457
-#define GSWIP_PCE_GCTRL_1_MAC_GLOCK BIT(2) /* MAC Address table lock */
-#define GSWIP_PCE_GCTRL_1_MAC_GLOCK_MOD BIT(3) /* Mac address table lock forwarding mode */
-#define GSWIP_PCE_PCTRL_0p(p) (0x480 + ((p) * 0xA))
-#define GSWIP_PCE_PCTRL_0_TVM BIT(5) /* Transparent VLAN mode */
-#define GSWIP_PCE_PCTRL_0_VREP BIT(6) /* VLAN Replace Mode */
-#define GSWIP_PCE_PCTRL_0_INGRESS BIT(11) /* Accept special tag in ingress */
-#define GSWIP_PCE_PCTRL_0_PSTATE_LISTEN 0x0
-#define GSWIP_PCE_PCTRL_0_PSTATE_RX 0x1
-#define GSWIP_PCE_PCTRL_0_PSTATE_TX 0x2
-#define GSWIP_PCE_PCTRL_0_PSTATE_LEARNING 0x3
-#define GSWIP_PCE_PCTRL_0_PSTATE_FORWARDING 0x7
-#define GSWIP_PCE_PCTRL_0_PSTATE_MASK GENMASK(2, 0)
-#define GSWIP_PCE_VCTRL(p) (0x485 + ((p) * 0xA))
-#define GSWIP_PCE_VCTRL_UVR BIT(0) /* Unknown VLAN Rule */
-#define GSWIP_PCE_VCTRL_VIMR BIT(3) /* VLAN Ingress Member violation rule */
-#define GSWIP_PCE_VCTRL_VEMR BIT(4) /* VLAN Egress Member violation rule */
-#define GSWIP_PCE_VCTRL_VSR BIT(5) /* VLAN Security */
-#define GSWIP_PCE_VCTRL_VID0 BIT(6) /* Priority Tagged Rule */
-#define GSWIP_PCE_DEFPVID(p) (0x486 + ((p) * 0xA))
-
-#define GSWIP_MAC_FLEN 0x8C5
-#define GSWIP_MAC_CTRL_0p(p) (0x903 + ((p) * 0xC))
-#define GSWIP_MAC_CTRL_0_PADEN BIT(8)
-#define GSWIP_MAC_CTRL_0_FCS_EN BIT(7)
-#define GSWIP_MAC_CTRL_0_FCON_MASK 0x0070
-#define GSWIP_MAC_CTRL_0_FCON_AUTO 0x0000
-#define GSWIP_MAC_CTRL_0_FCON_RX 0x0010
-#define GSWIP_MAC_CTRL_0_FCON_TX 0x0020
-#define GSWIP_MAC_CTRL_0_FCON_RXTX 0x0030
-#define GSWIP_MAC_CTRL_0_FCON_NONE 0x0040
-#define GSWIP_MAC_CTRL_0_FDUP_MASK 0x000C
-#define GSWIP_MAC_CTRL_0_FDUP_AUTO 0x0000
-#define GSWIP_MAC_CTRL_0_FDUP_EN 0x0004
-#define GSWIP_MAC_CTRL_0_FDUP_DIS 0x000C
-#define GSWIP_MAC_CTRL_0_GMII_MASK 0x0003
-#define GSWIP_MAC_CTRL_0_GMII_AUTO 0x0000
-#define GSWIP_MAC_CTRL_0_GMII_MII 0x0001
-#define GSWIP_MAC_CTRL_0_GMII_RGMII 0x0002
-#define GSWIP_MAC_CTRL_2p(p) (0x905 + ((p) * 0xC))
-#define GSWIP_MAC_CTRL_2_LCHKL BIT(2) /* Frame Length Check Long Enable */
-#define GSWIP_MAC_CTRL_2_MLEN BIT(3) /* Maximum Untagged Frame Lnegth */
-
-/* Ethernet Switch Fetch DMA Port Control Register */
-#define GSWIP_FDMA_PCTRLp(p) (0xA80 + ((p) * 0x6))
-#define GSWIP_FDMA_PCTRL_EN BIT(0) /* FDMA Port Enable */
-#define GSWIP_FDMA_PCTRL_STEN BIT(1) /* Special Tag Insertion Enable */
-#define GSWIP_FDMA_PCTRL_VLANMOD_MASK GENMASK(4, 3) /* VLAN Modification Control */
-#define GSWIP_FDMA_PCTRL_VLANMOD_SHIFT 3 /* VLAN Modification Control */
-#define GSWIP_FDMA_PCTRL_VLANMOD_DIS (0x0 << GSWIP_FDMA_PCTRL_VLANMOD_SHIFT)
-#define GSWIP_FDMA_PCTRL_VLANMOD_PRIO (0x1 << GSWIP_FDMA_PCTRL_VLANMOD_SHIFT)
-#define GSWIP_FDMA_PCTRL_VLANMOD_ID (0x2 << GSWIP_FDMA_PCTRL_VLANMOD_SHIFT)
-#define GSWIP_FDMA_PCTRL_VLANMOD_BOTH (0x3 << GSWIP_FDMA_PCTRL_VLANMOD_SHIFT)
-
-/* Ethernet Switch Store DMA Port Control Register */
-#define GSWIP_SDMA_PCTRLp(p) (0xBC0 + ((p) * 0x6))
-#define GSWIP_SDMA_PCTRL_EN BIT(0) /* SDMA Port Enable */
-#define GSWIP_SDMA_PCTRL_FCEN BIT(1) /* Flow Control Enable */
-#define GSWIP_SDMA_PCTRL_PAUFWD BIT(3) /* Pause Frame Forwarding */
-
-#define GSWIP_TABLE_ACTIVE_VLAN 0x01
-#define GSWIP_TABLE_VLAN_MAPPING 0x02
-#define GSWIP_TABLE_MAC_BRIDGE 0x0b
-#define GSWIP_TABLE_MAC_BRIDGE_KEY3_FID GENMASK(5, 0) /* Filtering identifier */
-#define GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT GENMASK(7, 4) /* Port on learned entries */
-#define GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC BIT(0) /* Static, non-aging entry */
-
-#define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-/* Maximum packet size supported by the switch. In theory this should be 10240,
- * but long packets currently cause lock-ups with an MTU of over 2526. Medium
- * packets are sometimes dropped (e.g. TCP over 2477, UDP over 2516-2519, ICMP
- * over 2526), hence an MTU value of 2400 seems safe. This issue only affects
- * packet reception. This is probably caused by the PPA engine, which is on the
- * RX part of the device. Packet transmission works properly up to 10240.
- */
-#define GSWIP_MAX_PACKET_LENGTH 2400
-
-struct gswip_hw_info {
- int max_ports;
- unsigned int allowed_cpu_ports;
- void (*phylink_get_caps)(struct dsa_switch *ds, int port,
- struct phylink_config *config);
-};
-
struct xway_gphy_match_data {
char *fe_firmware_name;
char *ge_firmware_name;
};
-struct gswip_gphy_fw {
- struct clk *clk_gate;
- struct reset_control *reset;
- u32 fw_addr_offset;
- char *fw_name;
-};
-
-struct gswip_vlan {
- struct net_device *bridge;
- u16 vid;
- u8 fid;
-};
-
-struct gswip_priv {
- __iomem void *gswip;
- __iomem void *mdio;
- __iomem void *mii;
- const struct gswip_hw_info *hw_info;
- const struct xway_gphy_match_data *gphy_fw_name_cfg;
- struct dsa_switch *ds;
- struct device *dev;
- struct regmap *rcu_regmap;
- struct gswip_vlan vlans[64];
- int num_gphy_fw;
- struct gswip_gphy_fw *gphy_fw;
- u32 port_vlan_filter;
- struct mutex pce_table_lock;
-};
-
struct gswip_pce_table_entry {
u16 index; // PCE_TBL_ADDR.ADDR = pData->table_index
u16 table; // PCE_TBL_CTRL.ADDR = pData->table
diff --git a/drivers/net/dsa/lantiq_gswip.h b/drivers/net/dsa/lantiq_gswip.h
new file mode 100644
index 000000000000..8703c947028a
--- /dev/null
+++ b/drivers/net/dsa/lantiq_gswip.h
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef __LANTIQ_GSWIP_H
+#define __LANTIQ_GSWIP_H
+
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <net/dsa.h>
+
+/* GSWIP MDIO Registers */
+#define GSWIP_MDIO_GLOB 0x00
+#define GSWIP_MDIO_GLOB_ENABLE BIT(15)
+#define GSWIP_MDIO_CTRL 0x08
+#define GSWIP_MDIO_CTRL_BUSY BIT(12)
+#define GSWIP_MDIO_CTRL_RD BIT(11)
+#define GSWIP_MDIO_CTRL_WR BIT(10)
+#define GSWIP_MDIO_CTRL_PHYAD_MASK 0x1f
+#define GSWIP_MDIO_CTRL_PHYAD_SHIFT 5
+#define GSWIP_MDIO_CTRL_REGAD_MASK 0x1f
+#define GSWIP_MDIO_READ 0x09
+#define GSWIP_MDIO_WRITE 0x0A
+#define GSWIP_MDIO_MDC_CFG0 0x0B
+#define GSWIP_MDIO_MDC_CFG1 0x0C
+#define GSWIP_MDIO_PHYp(p) (0x15 - (p))
+#define GSWIP_MDIO_PHY_LINK_MASK 0x6000
+#define GSWIP_MDIO_PHY_LINK_AUTO 0x0000
+#define GSWIP_MDIO_PHY_LINK_DOWN 0x4000
+#define GSWIP_MDIO_PHY_LINK_UP 0x2000
+#define GSWIP_MDIO_PHY_SPEED_MASK 0x1800
+#define GSWIP_MDIO_PHY_SPEED_AUTO 0x1800
+#define GSWIP_MDIO_PHY_SPEED_M10 0x0000
+#define GSWIP_MDIO_PHY_SPEED_M100 0x0800
+#define GSWIP_MDIO_PHY_SPEED_G1 0x1000
+#define GSWIP_MDIO_PHY_FDUP_MASK 0x0600
+#define GSWIP_MDIO_PHY_FDUP_AUTO 0x0000
+#define GSWIP_MDIO_PHY_FDUP_EN 0x0200
+#define GSWIP_MDIO_PHY_FDUP_DIS 0x0600
+#define GSWIP_MDIO_PHY_FCONTX_MASK 0x0180
+#define GSWIP_MDIO_PHY_FCONTX_AUTO 0x0000
+#define GSWIP_MDIO_PHY_FCONTX_EN 0x0100
+#define GSWIP_MDIO_PHY_FCONTX_DIS 0x0180
+#define GSWIP_MDIO_PHY_FCONRX_MASK 0x0060
+#define GSWIP_MDIO_PHY_FCONRX_AUTO 0x0000
+#define GSWIP_MDIO_PHY_FCONRX_EN 0x0020
+#define GSWIP_MDIO_PHY_FCONRX_DIS 0x0060
+#define GSWIP_MDIO_PHY_ADDR_MASK 0x001f
+#define GSWIP_MDIO_PHY_MASK (GSWIP_MDIO_PHY_ADDR_MASK | \
+ GSWIP_MDIO_PHY_FCONRX_MASK | \
+ GSWIP_MDIO_PHY_FCONTX_MASK | \
+ GSWIP_MDIO_PHY_LINK_MASK | \
+ GSWIP_MDIO_PHY_SPEED_MASK | \
+ GSWIP_MDIO_PHY_FDUP_MASK)
+
+/* GSWIP MII Registers */
+#define GSWIP_MII_CFGp(p) (0x2 * (p))
+#define GSWIP_MII_CFG_RESET BIT(15)
+#define GSWIP_MII_CFG_EN BIT(14)
+#define GSWIP_MII_CFG_ISOLATE BIT(13)
+#define GSWIP_MII_CFG_LDCLKDIS BIT(12)
+#define GSWIP_MII_CFG_RGMII_IBS BIT(8)
+#define GSWIP_MII_CFG_RMII_CLK BIT(7)
+#define GSWIP_MII_CFG_MODE_MIIP 0x0
+#define GSWIP_MII_CFG_MODE_MIIM 0x1
+#define GSWIP_MII_CFG_MODE_RMIIP 0x2
+#define GSWIP_MII_CFG_MODE_RMIIM 0x3
+#define GSWIP_MII_CFG_MODE_RGMII 0x4
+#define GSWIP_MII_CFG_MODE_GMII 0x9
+#define GSWIP_MII_CFG_MODE_MASK 0xf
+#define GSWIP_MII_CFG_RATE_M2P5 0x00
+#define GSWIP_MII_CFG_RATE_M25 0x10
+#define GSWIP_MII_CFG_RATE_M125 0x20
+#define GSWIP_MII_CFG_RATE_M50 0x30
+#define GSWIP_MII_CFG_RATE_AUTO 0x40
+#define GSWIP_MII_CFG_RATE_MASK 0x70
+#define GSWIP_MII_PCDU0 0x01
+#define GSWIP_MII_PCDU1 0x03
+#define GSWIP_MII_PCDU5 0x05
+#define GSWIP_MII_PCDU_TXDLY_MASK GENMASK(2, 0)
+#define GSWIP_MII_PCDU_RXDLY_MASK GENMASK(9, 7)
+
+/* GSWIP Core Registers */
+#define GSWIP_SWRES 0x000
+#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_2_0 0x100
+#define GSWIP_VERSION_2_1 0x021
+#define GSWIP_VERSION_2_2 0x122
+#define GSWIP_VERSION_2_2_ETC 0x022
+
+#define GSWIP_BM_RAM_VAL(x) (0x043 - (x))
+#define GSWIP_BM_RAM_ADDR 0x044
+#define GSWIP_BM_RAM_CTRL 0x045
+#define GSWIP_BM_RAM_CTRL_BAS BIT(15)
+#define GSWIP_BM_RAM_CTRL_OPMOD BIT(5)
+#define GSWIP_BM_RAM_CTRL_ADDR_MASK GENMASK(4, 0)
+#define GSWIP_BM_QUEUE_GCTRL 0x04A
+#define GSWIP_BM_QUEUE_GCTRL_GL_MOD BIT(10)
+/* buffer management Port Configuration Register */
+#define GSWIP_BM_PCFGp(p) (0x080 + ((p) * 2))
+#define GSWIP_BM_PCFG_CNTEN BIT(0) /* RMON Counter Enable */
+#define GSWIP_BM_PCFG_IGCNT BIT(1) /* Ingres Special Tag RMON count */
+/* buffer management Port Control Register */
+#define GSWIP_BM_RMON_CTRLp(p) (0x81 + ((p) * 2))
+#define GSWIP_BM_CTRL_RMON_RAM1_RES BIT(0) /* Software Reset for RMON RAM 1 */
+#define GSWIP_BM_CTRL_RMON_RAM2_RES BIT(1) /* Software Reset for RMON RAM 2 */
+
+/* PCE */
+#define GSWIP_PCE_TBL_KEY(x) (0x447 - (x))
+#define GSWIP_PCE_TBL_MASK 0x448
+#define GSWIP_PCE_TBL_VAL(x) (0x44D - (x))
+#define GSWIP_PCE_TBL_ADDR 0x44E
+#define GSWIP_PCE_TBL_CTRL 0x44F
+#define GSWIP_PCE_TBL_CTRL_BAS BIT(15)
+#define GSWIP_PCE_TBL_CTRL_TYPE BIT(13)
+#define GSWIP_PCE_TBL_CTRL_VLD BIT(12)
+#define GSWIP_PCE_TBL_CTRL_KEYFORM BIT(11)
+#define GSWIP_PCE_TBL_CTRL_GMAP_MASK GENMASK(10, 7)
+#define GSWIP_PCE_TBL_CTRL_OPMOD_MASK GENMASK(6, 5)
+#define GSWIP_PCE_TBL_CTRL_OPMOD_ADRD 0x00
+#define GSWIP_PCE_TBL_CTRL_OPMOD_ADWR 0x20
+#define GSWIP_PCE_TBL_CTRL_OPMOD_KSRD 0x40
+#define GSWIP_PCE_TBL_CTRL_OPMOD_KSWR 0x60
+#define GSWIP_PCE_TBL_CTRL_ADDR_MASK GENMASK(4, 0)
+#define GSWIP_PCE_PMAP1 0x453 /* Monitoring port map */
+#define GSWIP_PCE_PMAP2 0x454 /* Default Multicast port map */
+#define GSWIP_PCE_PMAP3 0x455 /* Default Unknown Unicast port map */
+#define GSWIP_PCE_GCTRL_0 0x456
+#define GSWIP_PCE_GCTRL_0_MTFL BIT(0) /* MAC Table Flushing */
+#define GSWIP_PCE_GCTRL_0_MC_VALID BIT(3)
+#define GSWIP_PCE_GCTRL_0_VLAN BIT(14) /* VLAN aware Switching */
+#define GSWIP_PCE_GCTRL_1 0x457
+#define GSWIP_PCE_GCTRL_1_MAC_GLOCK BIT(2) /* MAC Address table lock */
+#define GSWIP_PCE_GCTRL_1_MAC_GLOCK_MOD BIT(3) /* Mac address table lock forwarding mode */
+#define GSWIP_PCE_PCTRL_0p(p) (0x480 + ((p) * 0xA))
+#define GSWIP_PCE_PCTRL_0_TVM BIT(5) /* Transparent VLAN mode */
+#define GSWIP_PCE_PCTRL_0_VREP BIT(6) /* VLAN Replace Mode */
+#define GSWIP_PCE_PCTRL_0_INGRESS BIT(11) /* Accept special tag in ingress */
+#define GSWIP_PCE_PCTRL_0_PSTATE_LISTEN 0x0
+#define GSWIP_PCE_PCTRL_0_PSTATE_RX 0x1
+#define GSWIP_PCE_PCTRL_0_PSTATE_TX 0x2
+#define GSWIP_PCE_PCTRL_0_PSTATE_LEARNING 0x3
+#define GSWIP_PCE_PCTRL_0_PSTATE_FORWARDING 0x7
+#define GSWIP_PCE_PCTRL_0_PSTATE_MASK GENMASK(2, 0)
+#define GSWIP_PCE_VCTRL(p) (0x485 + ((p) * 0xA))
+#define GSWIP_PCE_VCTRL_UVR BIT(0) /* Unknown VLAN Rule */
+#define GSWIP_PCE_VCTRL_VIMR BIT(3) /* VLAN Ingress Member violation rule */
+#define GSWIP_PCE_VCTRL_VEMR BIT(4) /* VLAN Egress Member violation rule */
+#define GSWIP_PCE_VCTRL_VSR BIT(5) /* VLAN Security */
+#define GSWIP_PCE_VCTRL_VID0 BIT(6) /* Priority Tagged Rule */
+#define GSWIP_PCE_DEFPVID(p) (0x486 + ((p) * 0xA))
+
+#define GSWIP_MAC_FLEN 0x8C5
+#define GSWIP_MAC_CTRL_0p(p) (0x903 + ((p) * 0xC))
+#define GSWIP_MAC_CTRL_0_PADEN BIT(8)
+#define GSWIP_MAC_CTRL_0_FCS_EN BIT(7)
+#define GSWIP_MAC_CTRL_0_FCON_MASK 0x0070
+#define GSWIP_MAC_CTRL_0_FCON_AUTO 0x0000
+#define GSWIP_MAC_CTRL_0_FCON_RX 0x0010
+#define GSWIP_MAC_CTRL_0_FCON_TX 0x0020
+#define GSWIP_MAC_CTRL_0_FCON_RXTX 0x0030
+#define GSWIP_MAC_CTRL_0_FCON_NONE 0x0040
+#define GSWIP_MAC_CTRL_0_FDUP_MASK 0x000C
+#define GSWIP_MAC_CTRL_0_FDUP_AUTO 0x0000
+#define GSWIP_MAC_CTRL_0_FDUP_EN 0x0004
+#define GSWIP_MAC_CTRL_0_FDUP_DIS 0x000C
+#define GSWIP_MAC_CTRL_0_GMII_MASK 0x0003
+#define GSWIP_MAC_CTRL_0_GMII_AUTO 0x0000
+#define GSWIP_MAC_CTRL_0_GMII_MII 0x0001
+#define GSWIP_MAC_CTRL_0_GMII_RGMII 0x0002
+#define GSWIP_MAC_CTRL_2p(p) (0x905 + ((p) * 0xC))
+#define GSWIP_MAC_CTRL_2_LCHKL BIT(2) /* Frame Length Check Long Enable */
+#define GSWIP_MAC_CTRL_2_MLEN BIT(3) /* Maximum Untagged Frame Lnegth */
+
+/* Ethernet Switch Fetch DMA Port Control Register */
+#define GSWIP_FDMA_PCTRLp(p) (0xA80 + ((p) * 0x6))
+#define GSWIP_FDMA_PCTRL_EN BIT(0) /* FDMA Port Enable */
+#define GSWIP_FDMA_PCTRL_STEN BIT(1) /* Special Tag Insertion Enable */
+#define GSWIP_FDMA_PCTRL_VLANMOD_MASK GENMASK(4, 3) /* VLAN Modification Control */
+#define GSWIP_FDMA_PCTRL_VLANMOD_SHIFT 3 /* VLAN Modification Control */
+#define GSWIP_FDMA_PCTRL_VLANMOD_DIS (0x0 << GSWIP_FDMA_PCTRL_VLANMOD_SHIFT)
+#define GSWIP_FDMA_PCTRL_VLANMOD_PRIO (0x1 << GSWIP_FDMA_PCTRL_VLANMOD_SHIFT)
+#define GSWIP_FDMA_PCTRL_VLANMOD_ID (0x2 << GSWIP_FDMA_PCTRL_VLANMOD_SHIFT)
+#define GSWIP_FDMA_PCTRL_VLANMOD_BOTH (0x3 << GSWIP_FDMA_PCTRL_VLANMOD_SHIFT)
+
+/* Ethernet Switch Store DMA Port Control Register */
+#define GSWIP_SDMA_PCTRLp(p) (0xBC0 + ((p) * 0x6))
+#define GSWIP_SDMA_PCTRL_EN BIT(0) /* SDMA Port Enable */
+#define GSWIP_SDMA_PCTRL_FCEN BIT(1) /* Flow Control Enable */
+#define GSWIP_SDMA_PCTRL_PAUFWD BIT(3) /* Pause Frame Forwarding */
+
+#define GSWIP_TABLE_ACTIVE_VLAN 0x01
+#define GSWIP_TABLE_VLAN_MAPPING 0x02
+#define GSWIP_TABLE_MAC_BRIDGE 0x0b
+#define GSWIP_TABLE_MAC_BRIDGE_KEY3_FID GENMASK(5, 0) /* Filtering identifier */
+#define GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT GENMASK(7, 4) /* Port on learned entries */
+#define GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC BIT(0) /* Static, non-aging entry */
+
+#define XRX200_GPHY_FW_ALIGN (16 * 1024)
+
+/* Maximum packet size supported by the switch. In theory this should be 10240,
+ * but long packets currently cause lock-ups with an MTU of over 2526. Medium
+ * packets are sometimes dropped (e.g. TCP over 2477, UDP over 2516-2519, ICMP
+ * over 2526), hence an MTU value of 2400 seems safe. This issue only affects
+ * packet reception. This is probably caused by the PPA engine, which is on the
+ * RX part of the device. Packet transmission works properly up to 10240.
+ */
+#define GSWIP_MAX_PACKET_LENGTH 2400
+
+struct gswip_hw_info {
+ int max_ports;
+ unsigned int allowed_cpu_ports;
+ void (*phylink_get_caps)(struct dsa_switch *ds, int port,
+ struct phylink_config *config);
+};
+
+struct gswip_gphy_fw {
+ struct clk *clk_gate;
+ struct reset_control *reset;
+ u32 fw_addr_offset;
+ char *fw_name;
+};
+
+struct gswip_vlan {
+ struct net_device *bridge;
+ u16 vid;
+ u8 fid;
+};
+
+struct gswip_priv {
+ __iomem void *gswip;
+ __iomem void *mdio;
+ __iomem void *mii;
+ const struct gswip_hw_info *hw_info;
+ const struct xway_gphy_match_data *gphy_fw_name_cfg;
+ struct dsa_switch *ds;
+ struct device *dev;
+ struct regmap *rcu_regmap;
+ struct gswip_vlan vlans[64];
+ int num_gphy_fw;
+ struct gswip_gphy_fw *gphy_fw;
+ u32 port_vlan_filter;
+ struct mutex pce_table_lock;
+};
+
+#endif /* __LANTIQ_GSWIP_H */
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v3 4/8] net: dsa: lantiq_gswip: introduce bitmap for MII ports
2025-08-20 1:54 [PATCH net-next v3 0/8] net: dsa: lantiq_gswip: prepare for supporting new features Daniel Golle
` (2 preceding siblings ...)
2025-08-20 1:54 ` [PATCH net-next v3 3/8] net: dsa: lantiq_gswip: move definitions to header Daniel Golle
@ 2025-08-20 1:55 ` Daniel Golle
2025-08-20 1:55 ` [PATCH net-next v3 5/8] net: dsa: lantiq_gswip: load model-specific microcode Daniel Golle
` (3 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Daniel Golle @ 2025-08-20 1:55 UTC (permalink / raw)
To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Philipp Zabel,
Russell King, linux-kernel, netdev
Cc: Andreas Schirm, Lukas Stockmann, Alexander Sverdlin,
Peter Christen, Avinash Jayaraman, Bing tao Xu, Liang Xu,
Juraj Povazanec, Fanni (Fang-Yi) Chan, Benny (Ying-Tsan) Weng,
Livia M. Rosu, John Crispin
Instead of relying on hard-coded numbers for MII ports, introduce
a bitmap for MII ports.
This is done in order to prepare for supporting MaxLinear GSW1xx ICs
which got a different layout of ports.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
---
v3: no changes
v2:
- move comment before 'if' statement
- don't add unused sgmii_ports and phy_ports
- correct bitmask for XRX200 and XRX300 (they were swapped in v1/RFC)
drivers/net/dsa/lantiq_gswip.c | 14 +++++++++++---
drivers/net/dsa/lantiq_gswip.h | 1 +
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index b1b250fc4f61..d988839dce2f 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -183,14 +183,20 @@ static void gswip_mii_mask(struct gswip_priv *priv, u32 clear, u32 set,
static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 clear, u32 set,
int port)
{
- /* There's no MII_CFG register for the CPU port */
- if (!dsa_is_cpu_port(priv->ds, port))
- gswip_mii_mask(priv, clear, set, GSWIP_MII_CFGp(port));
+ /* MII_CFG register only exists for MII ports */
+ if (!(priv->hw_info->mii_ports & BIT(port)))
+ return;
+
+ gswip_mii_mask(priv, clear, set, GSWIP_MII_CFGp(port));
}
static void gswip_mii_mask_pcdu(struct gswip_priv *priv, u32 clear, u32 set,
int port)
{
+ /* MII_PCDU register only exists for MII ports */
+ if (!(priv->hw_info->mii_ports & BIT(port)))
+ return;
+
switch (port) {
case 0:
gswip_mii_mask(priv, clear, set, GSWIP_MII_PCDU0);
@@ -1993,12 +1999,14 @@ static void gswip_shutdown(struct platform_device *pdev)
static const struct gswip_hw_info gswip_xrx200 = {
.max_ports = 7,
.allowed_cpu_ports = BIT(6),
+ .mii_ports = BIT(0) | BIT(1) | BIT(5),
.phylink_get_caps = gswip_xrx200_phylink_get_caps,
};
static const struct gswip_hw_info gswip_xrx300 = {
.max_ports = 7,
.allowed_cpu_ports = BIT(6),
+ .mii_ports = BIT(0) | BIT(5),
.phylink_get_caps = gswip_xrx300_phylink_get_caps,
};
diff --git a/drivers/net/dsa/lantiq_gswip.h b/drivers/net/dsa/lantiq_gswip.h
index 8703c947028a..1bd05348f1e1 100644
--- a/drivers/net/dsa/lantiq_gswip.h
+++ b/drivers/net/dsa/lantiq_gswip.h
@@ -216,6 +216,7 @@
struct gswip_hw_info {
int max_ports;
unsigned int allowed_cpu_ports;
+ unsigned int mii_ports;
void (*phylink_get_caps)(struct dsa_switch *ds, int port,
struct phylink_config *config);
};
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v3 5/8] net: dsa: lantiq_gswip: load model-specific microcode
2025-08-20 1:54 [PATCH net-next v3 0/8] net: dsa: lantiq_gswip: prepare for supporting new features Daniel Golle
` (3 preceding siblings ...)
2025-08-20 1:55 ` [PATCH net-next v3 4/8] net: dsa: lantiq_gswip: introduce bitmap for MII ports Daniel Golle
@ 2025-08-20 1:55 ` Daniel Golle
2025-08-20 1:55 ` [PATCH net-next v3 6/8] net: dsa: lantiq_gswip: make DSA tag protocol model-specific Daniel Golle
` (2 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Daniel Golle @ 2025-08-20 1:55 UTC (permalink / raw)
To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Philipp Zabel,
Russell King, linux-kernel, netdev
Cc: Andreas Schirm, Lukas Stockmann, Alexander Sverdlin,
Peter Christen, Avinash Jayaraman, Bing tao Xu, Liang Xu,
Juraj Povazanec, Fanni (Fang-Yi) Chan, Benny (Ying-Tsan) Weng,
Livia M. Rosu, John Crispin
Load microcode as specified in struct hw_info instead of relying on
a single array of instructions. This is done in preparation to allow
loading different microcode for the MaxLinear GSW1xx family.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
---
v3: no changes
v2: no changes
drivers/net/dsa/lantiq_gswip.c | 14 +++++++++-----
drivers/net/dsa/lantiq_gswip.h | 9 +++++++++
drivers/net/dsa/lantiq_pce.h | 9 ++-------
3 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index d988839dce2f..1ce9ef425082 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -500,15 +500,15 @@ static int gswip_pce_load_microcode(struct gswip_priv *priv)
GSWIP_PCE_TBL_CTRL_OPMOD_ADWR, GSWIP_PCE_TBL_CTRL);
gswip_switch_w(priv, 0, GSWIP_PCE_TBL_MASK);
- for (i = 0; i < ARRAY_SIZE(gswip_pce_microcode); i++) {
+ for (i = 0; i < priv->hw_info->pce_microcode_size; i++) {
gswip_switch_w(priv, i, GSWIP_PCE_TBL_ADDR);
- gswip_switch_w(priv, gswip_pce_microcode[i].val_0,
+ gswip_switch_w(priv, (*priv->hw_info->pce_microcode)[i].val_0,
GSWIP_PCE_TBL_VAL(0));
- gswip_switch_w(priv, gswip_pce_microcode[i].val_1,
+ gswip_switch_w(priv, (*priv->hw_info->pce_microcode)[i].val_1,
GSWIP_PCE_TBL_VAL(1));
- gswip_switch_w(priv, gswip_pce_microcode[i].val_2,
+ gswip_switch_w(priv, (*priv->hw_info->pce_microcode)[i].val_2,
GSWIP_PCE_TBL_VAL(2));
- gswip_switch_w(priv, gswip_pce_microcode[i].val_3,
+ gswip_switch_w(priv, (*priv->hw_info->pce_microcode)[i].val_3,
GSWIP_PCE_TBL_VAL(3));
/* start the table access: */
@@ -2001,6 +2001,8 @@ static const struct gswip_hw_info gswip_xrx200 = {
.allowed_cpu_ports = BIT(6),
.mii_ports = BIT(0) | BIT(1) | BIT(5),
.phylink_get_caps = gswip_xrx200_phylink_get_caps,
+ .pce_microcode = &gswip_pce_microcode,
+ .pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
};
static const struct gswip_hw_info gswip_xrx300 = {
@@ -2008,6 +2010,8 @@ static const struct gswip_hw_info gswip_xrx300 = {
.allowed_cpu_ports = BIT(6),
.mii_ports = BIT(0) | BIT(5),
.phylink_get_caps = gswip_xrx300_phylink_get_caps,
+ .pce_microcode = &gswip_pce_microcode,
+ .pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
};
static const struct of_device_id gswip_of_match[] = {
diff --git a/drivers/net/dsa/lantiq_gswip.h b/drivers/net/dsa/lantiq_gswip.h
index 1bd05348f1e1..3c60f14673a7 100644
--- a/drivers/net/dsa/lantiq_gswip.h
+++ b/drivers/net/dsa/lantiq_gswip.h
@@ -213,10 +213,19 @@
*/
#define GSWIP_MAX_PACKET_LENGTH 2400
+struct gswip_pce_microcode {
+ u16 val_3;
+ u16 val_2;
+ u16 val_1;
+ u16 val_0;
+};
+
struct gswip_hw_info {
int max_ports;
unsigned int allowed_cpu_ports;
unsigned int mii_ports;
+ const struct gswip_pce_microcode (*pce_microcode)[];
+ size_t pce_microcode_size;
void (*phylink_get_caps)(struct dsa_switch *ds, int port,
struct phylink_config *config);
};
diff --git a/drivers/net/dsa/lantiq_pce.h b/drivers/net/dsa/lantiq_pce.h
index e2be31f3672a..659f9a0638d9 100644
--- a/drivers/net/dsa/lantiq_pce.h
+++ b/drivers/net/dsa/lantiq_pce.h
@@ -7,6 +7,8 @@
* Copyright (C) 2017 - 2018 Hauke Mehrtens <hauke@hauke-m.de>
*/
+#include "lantiq_gswip.h"
+
enum {
OUT_MAC0 = 0,
OUT_MAC1,
@@ -74,13 +76,6 @@ enum {
FLAG_NO, /*13*/
};
-struct gswip_pce_microcode {
- u16 val_3;
- u16 val_2;
- u16 val_1;
- u16 val_0;
-};
-
#define MC_ENTRY(val, msk, ns, out, len, type, flags, ipv4_len) \
{ val, msk, ((ns) << 10 | (out) << 4 | (len) >> 1),\
((len) & 1) << 15 | (type) << 13 | (flags) << 9 | (ipv4_len) << 8 }
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v3 6/8] net: dsa: lantiq_gswip: make DSA tag protocol model-specific
2025-08-20 1:54 [PATCH net-next v3 0/8] net: dsa: lantiq_gswip: prepare for supporting new features Daniel Golle
` (4 preceding siblings ...)
2025-08-20 1:55 ` [PATCH net-next v3 5/8] net: dsa: lantiq_gswip: load model-specific microcode Daniel Golle
@ 2025-08-20 1:55 ` Daniel Golle
2025-08-20 1:55 ` [PATCH net-next v3 7/8] net: dsa: lantiq_gswip: store switch API version in priv Daniel Golle
2025-08-20 1:56 ` [PATCH net-next v3 8/8] net: dsa: lantiq_gswip: add support for SWAPI version 2.3 Daniel Golle
7 siblings, 0 replies; 13+ messages in thread
From: Daniel Golle @ 2025-08-20 1:55 UTC (permalink / raw)
To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Philipp Zabel,
Russell King, linux-kernel, netdev
Cc: Andreas Schirm, Lukas Stockmann, Alexander Sverdlin,
Peter Christen, Avinash Jayaraman, Bing tao Xu, Liang Xu,
Juraj Povazanec, Fanni (Fang-Yi) Chan, Benny (Ying-Tsan) Weng,
Livia M. Rosu, John Crispin
While the older Lantiq / Intel which are currently supported all use
the DSA_TAG_GSWIP tagging protocol, newer MaxLinear GSW1xx modules use
another 8-byte tagging protocol. Move the tag protocol information to
struct gswip_hw_info to make it possible for new models to specify
a different tagging protocol.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
---
v3: no changes
v2: no changes
drivers/net/dsa/lantiq_gswip.c | 6 +++++-
drivers/net/dsa/lantiq_gswip.h | 1 +
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index 1ce9ef425082..f8a43c351649 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -659,7 +659,9 @@ static enum dsa_tag_protocol gswip_get_tag_protocol(struct dsa_switch *ds,
int port,
enum dsa_tag_protocol mp)
{
- return DSA_TAG_PROTO_GSWIP;
+ struct gswip_priv *priv = ds->priv;
+
+ return priv->hw_info->tag_protocol;
}
static int gswip_vlan_active_create(struct gswip_priv *priv,
@@ -2003,6 +2005,7 @@ static const struct gswip_hw_info gswip_xrx200 = {
.phylink_get_caps = gswip_xrx200_phylink_get_caps,
.pce_microcode = &gswip_pce_microcode,
.pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
+ .tag_protocol = DSA_TAG_PROTO_GSWIP,
};
static const struct gswip_hw_info gswip_xrx300 = {
@@ -2012,6 +2015,7 @@ static const struct gswip_hw_info gswip_xrx300 = {
.phylink_get_caps = gswip_xrx300_phylink_get_caps,
.pce_microcode = &gswip_pce_microcode,
.pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
+ .tag_protocol = DSA_TAG_PROTO_GSWIP,
};
static const struct of_device_id gswip_of_match[] = {
diff --git a/drivers/net/dsa/lantiq_gswip.h b/drivers/net/dsa/lantiq_gswip.h
index 3c60f14673a7..0b7b6db4eab9 100644
--- a/drivers/net/dsa/lantiq_gswip.h
+++ b/drivers/net/dsa/lantiq_gswip.h
@@ -226,6 +226,7 @@ struct gswip_hw_info {
unsigned int mii_ports;
const struct gswip_pce_microcode (*pce_microcode)[];
size_t pce_microcode_size;
+ enum dsa_tag_protocol tag_protocol;
void (*phylink_get_caps)(struct dsa_switch *ds, int port,
struct phylink_config *config);
};
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v3 7/8] net: dsa: lantiq_gswip: store switch API version in priv
2025-08-20 1:54 [PATCH net-next v3 0/8] net: dsa: lantiq_gswip: prepare for supporting new features Daniel Golle
` (5 preceding siblings ...)
2025-08-20 1:55 ` [PATCH net-next v3 6/8] net: dsa: lantiq_gswip: make DSA tag protocol model-specific Daniel Golle
@ 2025-08-20 1:55 ` Daniel Golle
2025-08-20 23:57 ` Daniel Golle
2025-08-20 1:56 ` [PATCH net-next v3 8/8] net: dsa: lantiq_gswip: add support for SWAPI version 2.3 Daniel Golle
7 siblings, 1 reply; 13+ messages in thread
From: Daniel Golle @ 2025-08-20 1:55 UTC (permalink / raw)
To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Philipp Zabel,
Russell King, linux-kernel, netdev
Cc: Andreas Schirm, Lukas Stockmann, Alexander Sverdlin,
Peter Christen, Avinash Jayaraman, Bing tao Xu, Liang Xu,
Juraj Povazanec, Fanni (Fang-Yi) Chan, Benny (Ying-Tsan) Weng,
Livia M. Rosu, John Crispin
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@makrotopia.org>
---
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);
+
/* 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
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v3 8/8] net: dsa: lantiq_gswip: add support for SWAPI version 2.3
2025-08-20 1:54 [PATCH net-next v3 0/8] net: dsa: lantiq_gswip: prepare for supporting new features Daniel Golle
` (6 preceding siblings ...)
2025-08-20 1:55 ` [PATCH net-next v3 7/8] net: dsa: lantiq_gswip: store switch API version in priv Daniel Golle
@ 2025-08-20 1:56 ` Daniel Golle
7 siblings, 0 replies; 13+ messages in thread
From: Daniel Golle @ 2025-08-20 1:56 UTC (permalink / raw)
To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Philipp Zabel,
Russell King, linux-kernel, netdev
Cc: Andreas Schirm, Lukas Stockmann, Alexander Sverdlin,
Peter Christen, Avinash Jayaraman, Bing tao Xu, Liang Xu,
Juraj Povazanec, Fanni (Fang-Yi) Chan, Benny (Ying-Tsan) Weng,
Livia M. Rosu, John Crispin
Add definition for switch API version 2.3 and a macro to make comparing
the switch hardware version with the (byte-swapped) version macros more
conveniant.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
---
v3: no changes
v2: no changes
drivers/net/dsa/lantiq_gswip.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/dsa/lantiq_gswip.h b/drivers/net/dsa/lantiq_gswip.h
index 077d1928149b..5cebb051ac90 100644
--- a/drivers/net/dsa/lantiq_gswip.h
+++ b/drivers/net/dsa/lantiq_gswip.h
@@ -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 */
@@ -93,6 +94,8 @@
#define GSWIP_VERSION_2_1 0x021
#define GSWIP_VERSION_2_2 0x122
#define GSWIP_VERSION_2_2_ETC 0x022
+#define GSWIP_VERSION_2_3 0x023
+#define GSWIP_VERSION_GE(priv, ver) ((priv)->version >= swab16(ver))
#define GSWIP_BM_RAM_VAL(x) (0x043 - (x))
#define GSWIP_BM_RAM_ADDR 0x044
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v3 7/8] net: dsa: lantiq_gswip: store switch API version in priv
2025-08-20 1:55 ` [PATCH net-next v3 7/8] net: dsa: lantiq_gswip: store switch API version in priv Daniel Golle
@ 2025-08-20 23:57 ` Daniel Golle
2025-08-21 2:58 ` Andrew Lunn
0 siblings, 1 reply; 13+ messages in thread
From: Daniel Golle @ 2025-08-20 23:57 UTC (permalink / raw)
To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Philipp Zabel,
Russell King, linux-kernel, netdev
Cc: Andreas Schirm, Lukas Stockmann, Alexander Sverdlin,
Peter Christen, Avinash Jayaraman, Bing tao Xu, Liang Xu,
Juraj Povazanec, Fanni (Fang-Yi) Chan, Benny (Ying-Tsan) Weng,
Livia M. Rosu, John Crispin
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@makrotopia.org>
> ---
> 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
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v3 7/8] net: dsa: lantiq_gswip: store switch API version in priv
2025-08-20 23:57 ` Daniel Golle
@ 2025-08-21 2:58 ` Andrew Lunn
2025-08-21 10:50 ` Daniel Golle
0 siblings, 1 reply; 13+ messages in thread
From: Andrew Lunn @ 2025-08-21 2:58 UTC (permalink / raw)
To: Daniel Golle
Cc: Hauke Mehrtens, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Philipp Zabel, Russell King,
linux-kernel, netdev, Andreas Schirm, Lukas Stockmann,
Alexander Sverdlin, Peter Christen, Avinash Jayaraman,
Bing tao Xu, Liang Xu, Juraj Povazanec, Fanni (Fang-Yi) Chan,
Benny (Ying-Tsan) Weng, Livia M. Rosu, John Crispin
> > + 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.
I agree that all MDIO bus registers are host endian, 16 bit. The shift
register in the hardware is responsible for putting the bits on the
wire in the correct order for MDIO.
> 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.
How is this described in the datasheet? And is version special, or do
all registers need swapping?
Andrew
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v3 7/8] net: dsa: lantiq_gswip: store switch API version in priv
2025-08-21 2:58 ` Andrew Lunn
@ 2025-08-21 10:50 ` Daniel Golle
2025-08-21 14:15 ` Andrew Lunn
0 siblings, 1 reply; 13+ messages in thread
From: Daniel Golle @ 2025-08-21 10:50 UTC (permalink / raw)
To: Andrew Lunn
Cc: Hauke Mehrtens, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Philipp Zabel, Russell King,
linux-kernel, netdev, Andreas Schirm, Lukas Stockmann,
Alexander Sverdlin, Peter Christen, Avinash Jayaraman,
Bing tao Xu, Liang Xu, Juraj Povazanec, Fanni (Fang-Yi) Chan,
Benny (Ying-Tsan) Weng, Livia M. Rosu, John Crispin
On Thu, Aug 21, 2025 at 04:58:23AM +0200, Andrew Lunn wrote:
> > > + 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.
>
> I agree that all MDIO bus registers are host endian, 16 bit. The shift
> register in the hardware is responsible for putting the bits on the
> wire in the correct order for MDIO.
>
> > 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.
>
> How is this described in the datasheet? And is version special, or do
> all registers need swapping?
The (anyway public) datasheets I have access to don't describe the VERSION
register at all. In the existing precompiler macros, however, you can see
that most-significant and least-significant byte are swapped. REV is
more significant than MOD:
#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_2_0 0x100
#define GSWIP_VERSION_2_1 0x021
#define GSWIP_VERSION_2_2 0x122
#define GSWIP_VERSION_2_2_ETC 0x022
Now I'd like to add
#define GSWIP_VERSION_2_3 0x023
and then have a simple way to make features available starting from a
GSWIP_VERSION. Now in order for GSWIP_VERSION_2_3 to be greater than
GSWIP_VERSION_2_2, and GSWIP_VERSION_2_1 to be greater than
GSWIP_VERSION_2_0, the bytes need to be swapped.
I don't think the vendor even considered any specific order of the two
bytes but just defines them as separate 8-bit fields, considering it a
16-bit unsigned integer is my interpretation which came from the need for
comparability.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v3 7/8] net: dsa: lantiq_gswip: store switch API version in priv
2025-08-21 10:50 ` Daniel Golle
@ 2025-08-21 14:15 ` Andrew Lunn
0 siblings, 0 replies; 13+ messages in thread
From: Andrew Lunn @ 2025-08-21 14:15 UTC (permalink / raw)
To: Daniel Golle
Cc: Hauke Mehrtens, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Philipp Zabel, Russell King,
linux-kernel, netdev, Andreas Schirm, Lukas Stockmann,
Alexander Sverdlin, Peter Christen, Avinash Jayaraman,
Bing tao Xu, Liang Xu, Juraj Povazanec, Fanni (Fang-Yi) Chan,
Benny (Ying-Tsan) Weng, Livia M. Rosu, John Crispin
> The (anyway public) datasheets I have access to don't describe the VERSION
> register at all. In the existing precompiler macros, however, you can see
> that most-significant and least-significant byte are swapped. REV is
> more significant than MOD:
>
> #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_2_0 0x100
> #define GSWIP_VERSION_2_1 0x021
> #define GSWIP_VERSION_2_2 0x122
> #define GSWIP_VERSION_2_2_ETC 0x022
>
> Now I'd like to add
> #define GSWIP_VERSION_2_3 0x023
>
> and then have a simple way to make features available starting from a
> GSWIP_VERSION. Now in order for GSWIP_VERSION_2_3 to be greater than
> GSWIP_VERSION_2_2, and GSWIP_VERSION_2_1 to be greater than
> GSWIP_VERSION_2_0, the bytes need to be swapped.
>
> I don't think the vendor even considered any specific order of the two
> bytes but just defines them as separate 8-bit fields, considering it a
> 16-bit unsigned integer is my interpretation which came from the need for
> comparability.
It would be good to put some of this into the commit message and
comments in the code. That the hardware has the 'major/minor' version
bytes in the wrong order preventing numerical comparisons. To make it
obvious, rather than use swap16(), maybe actually extract the major
and minor, and then construct the version in the form you want?
Andrew
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-08-21 14:15 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-20 1:54 [PATCH net-next v3 0/8] net: dsa: lantiq_gswip: prepare for supporting new features Daniel Golle
2025-08-20 1:54 ` [PATCH net-next v3 1/8] net: dsa: lantiq_gswip: deduplicate dsa_switch_ops Daniel Golle
2025-08-20 1:54 ` [PATCH net-next v3 2/8] net: dsa: lantiq_gswip: prepare for more CPU port options Daniel Golle
2025-08-20 1:54 ` [PATCH net-next v3 3/8] net: dsa: lantiq_gswip: move definitions to header Daniel Golle
2025-08-20 1:55 ` [PATCH net-next v3 4/8] net: dsa: lantiq_gswip: introduce bitmap for MII ports Daniel Golle
2025-08-20 1:55 ` [PATCH net-next v3 5/8] net: dsa: lantiq_gswip: load model-specific microcode Daniel Golle
2025-08-20 1:55 ` [PATCH net-next v3 6/8] net: dsa: lantiq_gswip: make DSA tag protocol model-specific Daniel Golle
2025-08-20 1:55 ` [PATCH net-next v3 7/8] net: dsa: lantiq_gswip: store switch API version in priv Daniel Golle
2025-08-20 23:57 ` Daniel Golle
2025-08-21 2:58 ` Andrew Lunn
2025-08-21 10:50 ` Daniel Golle
2025-08-21 14:15 ` Andrew Lunn
2025-08-20 1:56 ` [PATCH net-next v3 8/8] net: dsa: lantiq_gswip: add support for SWAPI version 2.3 Daniel Golle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).