--- /dev/null
+From 73b7a6047971aa6ce4a70fc4901964d14f077171 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Wed, 6 Jan 2021 22:32:02 +0100
+Subject: [PATCH] net: dsa: bcm_sf2: support BCM4908's integrated switch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM4908 family SoCs come with integrated Starfighter 2 switch. Its
+registers layout it a mix of BCM7278 and BCM7445. It has 5 integrated
+PHYs and 8 ports. It also supports RGMII and SerDes.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Link: https://lore.kernel.org/r/20210106213202.17459-3-zajec5@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 14 +++++++++++++
+ drivers/net/dsa/b53/b53_priv.h | 1 +
+ drivers/net/dsa/bcm_sf2.c | 36 +++++++++++++++++++++++++++++---
+ drivers/net/dsa/bcm_sf2_regs.h | 1 +
+ 4 files changed, 49 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2260,6 +2260,22 @@ static const struct b53_chip_data b53_sw
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+ },
++ /* Starfighter 2 */
++ {
++ .chip_id = BCM4908_DEVICE_ID,
++ .dev_name = "BCM4908",
++ .vlans = 4096,
++ .enabled_ports = 0x1bf,
++#if 0
++ .arl_bins = 4,
++ .arl_buckets = 256,
++#endif
++ .cpu_port = 8, /* TODO: ports 4, 5, 8 */
++ .vta_regs = B53_VTA_REGS,
++ .duplex_reg = B53_DUPLEX_STAT_GE,
++ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
++ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ },
+ {
+ .chip_id = BCM7445_DEVICE_ID,
+ .dev_name = "BCM7445",
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -64,6 +64,7 @@ struct b53_io_ops {
+ #define B53_INVALID_LANE 0xff
+
+ enum {
++ BCM4908_DEVICE_ID = 0x4908,
+ BCM5325_DEVICE_ID = 0x25,
+ BCM5365_DEVICE_ID = 0x65,
+ BCM5389_DEVICE_ID = 0x89,
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -61,7 +61,8 @@ static void bcm_sf2_imp_setup(struct dsa
+ b53_brcm_hdr_setup(ds, port);
+
+ if (port == 8) {
+- if (priv->type == BCM7445_DEVICE_ID)
++ if (priv->type == BCM4908_DEVICE_ID ||
++ priv->type == BCM7445_DEVICE_ID)
+ offset = CORE_STS_OVERRIDE_IMP;
+ else
+ offset = CORE_STS_OVERRIDE_IMP2;
+@@ -546,7 +547,8 @@ static void bcm_sf2_sw_mac_config(struct
+ if (port == core_readl(priv, CORE_IMP0_PRT_ID))
+ return;
+
+- if (priv->type == BCM7445_DEVICE_ID)
++ if (priv->type == BCM4908_DEVICE_ID ||
++ priv->type == BCM7445_DEVICE_ID)
+ offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
+ else
+ offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
+@@ -988,6 +990,30 @@ struct bcm_sf2_of_data {
+ unsigned int num_cfp_rules;
+ };
+
++static const u16 bcm_sf2_4908_reg_offsets[] = {
++ [REG_SWITCH_CNTRL] = 0x00,
++ [REG_SWITCH_STATUS] = 0x04,
++ [REG_DIR_DATA_WRITE] = 0x08,
++ [REG_DIR_DATA_READ] = 0x0c,
++ [REG_SWITCH_REVISION] = 0x10,
++ [REG_PHY_REVISION] = 0x14,
++ [REG_SPHY_CNTRL] = 0x24,
++ [REG_CROSSBAR] = 0xc8,
++ [REG_RGMII_0_CNTRL] = 0xe0,
++ [REG_RGMII_1_CNTRL] = 0xec,
++ [REG_RGMII_2_CNTRL] = 0xf8,
++ [REG_LED_0_CNTRL] = 0x40,
++ [REG_LED_1_CNTRL] = 0x4c,
++ [REG_LED_2_CNTRL] = 0x58,
++};
++
++static const struct bcm_sf2_of_data bcm_sf2_4908_data = {
++ .type = BCM4908_DEVICE_ID,
++ .core_reg_align = 0,
++ .reg_offsets = bcm_sf2_4908_reg_offsets,
++ .num_cfp_rules = 0, /* FIXME */
++};
++
+ /* Register offsets for the SWITCH_REG_* block */
+ static const u16 bcm_sf2_7445_reg_offsets[] = {
+ [REG_SWITCH_CNTRL] = 0x00,
+@@ -1036,6 +1062,9 @@ static const struct bcm_sf2_of_data bcm_
+ };
+
+ static const struct of_device_id bcm_sf2_of_match[] = {
++ { .compatible = "brcm,bcm4908-switch",
++ .data = &bcm_sf2_4908_data
++ },
+ { .compatible = "brcm,bcm7445-switch-v4.0",
+ .data = &bcm_sf2_7445_data
+ },
+--- a/drivers/net/dsa/bcm_sf2_regs.h
++++ b/drivers/net/dsa/bcm_sf2_regs.h
+@@ -17,6 +17,7 @@ enum bcm_sf2_reg_offs {
+ REG_SWITCH_REVISION,
+ REG_PHY_REVISION,
+ REG_SPHY_CNTRL,
++ REG_CROSSBAR,
+ REG_RGMII_0_CNTRL,
+ REG_RGMII_1_CNTRL,
+ REG_RGMII_2_CNTRL,
--- /dev/null
+From 8373a0fe9c7160a55482effa8a3f725efd3f8434 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Wed, 10 Mar 2021 13:51:59 +0100
+Subject: [PATCH] net: dsa: bcm_sf2: use 2 Gbps IMP port link on BCM4908
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM4908 uses 2 Gbps link between switch and the Ethernet interface.
+Without this BCM4908 devices were able to achieve only 2 x ~895 Mb/s.
+This allows handling e.g. NAT traffic with 940 Mb/s.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -70,7 +70,10 @@ static void bcm_sf2_imp_setup(struct dsa
+ /* Force link status for IMP port */
+ reg = core_readl(priv, offset);
+ reg |= (MII_SW_OR | LINK_STS);
+- reg &= ~GMII_SPEED_UP_2G;
++ if (priv->type == BCM4908_DEVICE_ID)
++ reg |= GMII_SPEED_UP_2G;
++ else
++ reg &= ~GMII_SPEED_UP_2G;
+ core_writel(priv, reg, offset);
+
+ /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */
+++ /dev/null
-From 73b7a6047971aa6ce4a70fc4901964d14f077171 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 6 Jan 2021 22:32:02 +0100
-Subject: [PATCH] net: dsa: bcm_sf2: support BCM4908's integrated switch
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM4908 family SoCs come with integrated Starfighter 2 switch. Its
-registers layout it a mix of BCM7278 and BCM7445. It has 5 integrated
-PHYs and 8 ports. It also supports RGMII and SerDes.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-Link: https://lore.kernel.org/r/20210106213202.17459-3-zajec5@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 14 +++++++++++++
- drivers/net/dsa/b53/b53_priv.h | 1 +
- drivers/net/dsa/bcm_sf2.c | 36 +++++++++++++++++++++++++++++---
- drivers/net/dsa/bcm_sf2_regs.h | 1 +
- 4 files changed, 49 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2260,6 +2260,22 @@ static const struct b53_chip_data b53_sw
- .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
- .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
- },
-+ /* Starfighter 2 */
-+ {
-+ .chip_id = BCM4908_DEVICE_ID,
-+ .dev_name = "BCM4908",
-+ .vlans = 4096,
-+ .enabled_ports = 0x1bf,
-+#if 0
-+ .arl_bins = 4,
-+ .arl_buckets = 256,
-+#endif
-+ .cpu_port = 8, /* TODO: ports 4, 5, 8 */
-+ .vta_regs = B53_VTA_REGS,
-+ .duplex_reg = B53_DUPLEX_STAT_GE,
-+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+ },
- {
- .chip_id = BCM7445_DEVICE_ID,
- .dev_name = "BCM7445",
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -64,6 +64,7 @@ struct b53_io_ops {
- #define B53_INVALID_LANE 0xff
-
- enum {
-+ BCM4908_DEVICE_ID = 0x4908,
- BCM5325_DEVICE_ID = 0x25,
- BCM5365_DEVICE_ID = 0x65,
- BCM5389_DEVICE_ID = 0x89,
---- a/drivers/net/dsa/bcm_sf2.c
-+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -61,7 +61,8 @@ static void bcm_sf2_imp_setup(struct dsa
- b53_brcm_hdr_setup(ds, port);
-
- if (port == 8) {
-- if (priv->type == BCM7445_DEVICE_ID)
-+ if (priv->type == BCM4908_DEVICE_ID ||
-+ priv->type == BCM7445_DEVICE_ID)
- offset = CORE_STS_OVERRIDE_IMP;
- else
- offset = CORE_STS_OVERRIDE_IMP2;
-@@ -546,7 +547,8 @@ static void bcm_sf2_sw_mac_config(struct
- if (port == core_readl(priv, CORE_IMP0_PRT_ID))
- return;
-
-- if (priv->type == BCM7445_DEVICE_ID)
-+ if (priv->type == BCM4908_DEVICE_ID ||
-+ priv->type == BCM7445_DEVICE_ID)
- offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
- else
- offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
-@@ -988,6 +990,30 @@ struct bcm_sf2_of_data {
- unsigned int num_cfp_rules;
- };
-
-+static const u16 bcm_sf2_4908_reg_offsets[] = {
-+ [REG_SWITCH_CNTRL] = 0x00,
-+ [REG_SWITCH_STATUS] = 0x04,
-+ [REG_DIR_DATA_WRITE] = 0x08,
-+ [REG_DIR_DATA_READ] = 0x0c,
-+ [REG_SWITCH_REVISION] = 0x10,
-+ [REG_PHY_REVISION] = 0x14,
-+ [REG_SPHY_CNTRL] = 0x24,
-+ [REG_CROSSBAR] = 0xc8,
-+ [REG_RGMII_0_CNTRL] = 0xe0,
-+ [REG_RGMII_1_CNTRL] = 0xec,
-+ [REG_RGMII_2_CNTRL] = 0xf8,
-+ [REG_LED_0_CNTRL] = 0x40,
-+ [REG_LED_1_CNTRL] = 0x4c,
-+ [REG_LED_2_CNTRL] = 0x58,
-+};
-+
-+static const struct bcm_sf2_of_data bcm_sf2_4908_data = {
-+ .type = BCM4908_DEVICE_ID,
-+ .core_reg_align = 0,
-+ .reg_offsets = bcm_sf2_4908_reg_offsets,
-+ .num_cfp_rules = 0, /* FIXME */
-+};
-+
- /* Register offsets for the SWITCH_REG_* block */
- static const u16 bcm_sf2_7445_reg_offsets[] = {
- [REG_SWITCH_CNTRL] = 0x00,
-@@ -1036,6 +1062,9 @@ static const struct bcm_sf2_of_data bcm_
- };
-
- static const struct of_device_id bcm_sf2_of_match[] = {
-+ { .compatible = "brcm,bcm4908-switch",
-+ .data = &bcm_sf2_4908_data
-+ },
- { .compatible = "brcm,bcm7445-switch-v4.0",
- .data = &bcm_sf2_7445_data
- },
---- a/drivers/net/dsa/bcm_sf2_regs.h
-+++ b/drivers/net/dsa/bcm_sf2_regs.h
-@@ -17,6 +17,7 @@ enum bcm_sf2_reg_offs {
- REG_SWITCH_REVISION,
- REG_PHY_REVISION,
- REG_SPHY_CNTRL,
-+ REG_CROSSBAR,
- REG_RGMII_0_CNTRL,
- REG_RGMII_1_CNTRL,
- REG_RGMII_2_CNTRL,
--- /dev/null
+From 01488a0ccd9abe15565bed50a45afcddbb0fe199 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Fri, 12 Mar 2021 11:41:07 +0100
+Subject: [PATCH] net: dsa: bcm_sf2: store PHY interface/mode in port structure
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It's needed later for proper switch / crossbar setup.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2.c | 16 ++++++++++++----
+ drivers/net/dsa/bcm_sf2.h | 1 +
+ 2 files changed, 13 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -385,8 +385,9 @@ static void bcm_sf2_intr_disable(struct
+ static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv,
+ struct device_node *dn)
+ {
++ struct device *dev = priv->dev->ds->dev;
++ struct bcm_sf2_port_status *port_st;
+ struct device_node *port;
+- int mode;
+ unsigned int port_num;
+
+ priv->moca_port = -1;
+@@ -395,19 +396,26 @@ static void bcm_sf2_identify_ports(struc
+ if (of_property_read_u32(port, "reg", &port_num))
+ continue;
+
++ if (port_num >= DSA_MAX_PORTS) {
++ dev_err(dev, "Invalid port number %d\n", port_num);
++ continue;
++ }
++
++ port_st = &priv->port_sts[port_num];
++
+ /* Internal PHYs get assigned a specific 'phy-mode' property
+ * value: "internal" to help flag them before MDIO probing
+ * has completed, since they might be turned off at that
+ * time
+ */
+- mode = of_get_phy_mode(port);
+- if (mode < 0)
++ port_st->mode = of_get_phy_mode(port);
++ if (port_st->mode < 0)
+ continue;
+
+- if (mode == PHY_INTERFACE_MODE_INTERNAL)
++ if (port_st->mode == PHY_INTERFACE_MODE_INTERNAL)
+ priv->int_phy_mask |= 1 << port_num;
+
+- if (mode == PHY_INTERFACE_MODE_MOCA)
++ if (port_st->mode == PHY_INTERFACE_MODE_MOCA)
+ priv->moca_port = port_num;
+
+ if (of_property_read_bool(port, "brcm,use-bcm-hdr"))
+--- a/drivers/net/dsa/bcm_sf2.h
++++ b/drivers/net/dsa/bcm_sf2.h
+@@ -43,6 +43,7 @@ struct bcm_sf2_hw_params {
+ #define BCM_SF2_REGS_NUM 6
+
+ struct bcm_sf2_port_status {
++ int mode;
+ unsigned int link;
+ };
+
--- /dev/null
+From a9349f08ec6c1251d41ef167d27a15cc39bc5b97 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Fri, 12 Mar 2021 11:41:08 +0100
+Subject: [PATCH] net: dsa: bcm_sf2: setup BCM4908 internal crossbar
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+On some SoCs (e.g. BCM4908, BCM631[345]8) SF2 has an integrated
+crossbar. It allows connecting its selected external ports to internal
+ports. It's used by vendors to handle custom Ethernet setups.
+
+BCM4908 has following 3x2 crossbar. On Asus GT-AC5300 rgmii is used for
+connecting external BCM53134S switch. GPHY4 is usually used for WAN
+port. More fancy devices use SerDes for 2.5 Gbps Ethernet.
+
+ ┌──────────┐
+SerDes ─── 0 ─┤ │
+ │ 3x2 ├─ 0 ─── switch port 7
+ GPHY4 ─── 1 ─┤ │
+ │ crossbar ├─ 1 ─── runner (accelerator)
+ rgmii ─── 2 ─┤ │
+ └──────────┘
+
+Use setup data based on DT info to configure BCM4908's switch port 7.
+Right now only GPHY and rgmii variants are supported. Handling SerDes
+can be implemented later.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/bcm_sf2.c | 45 ++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/bcm_sf2.h | 1 +
+ drivers/net/dsa/bcm_sf2_regs.h | 7 ++++++
+ 3 files changed, 53 insertions(+)
+
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -374,6 +374,44 @@ static int bcm_sf2_sw_rst(struct bcm_sf2
+ return 0;
+ }
+
++static void bcm_sf2_crossbar_setup(struct bcm_sf2_priv *priv)
++{
++ struct device *dev = priv->dev->ds->dev;
++ int shift;
++ u32 mask;
++ u32 reg;
++ int i;
++
++ mask = BIT(priv->num_crossbar_int_ports) - 1;
++
++ reg = reg_readl(priv, REG_CROSSBAR);
++ switch (priv->type) {
++ case BCM4908_DEVICE_ID:
++ shift = CROSSBAR_BCM4908_INT_P7 * priv->num_crossbar_int_ports;
++ reg &= ~(mask << shift);
++ if (0) /* FIXME */
++ reg |= CROSSBAR_BCM4908_EXT_SERDES << shift;
++ else if (priv->int_phy_mask & BIT(7))
++ reg |= CROSSBAR_BCM4908_EXT_GPHY4 << shift;
++ else if (phy_interface_mode_is_rgmii(priv->port_sts[7].mode))
++ reg |= CROSSBAR_BCM4908_EXT_RGMII << shift;
++ else if (WARN(1, "Invalid port mode\n"))
++ return;
++ break;
++ default:
++ return;
++ }
++ reg_writel(priv, reg, REG_CROSSBAR);
++
++ reg = reg_readl(priv, REG_CROSSBAR);
++ for (i = 0; i < priv->num_crossbar_int_ports; i++) {
++ shift = i * priv->num_crossbar_int_ports;
++
++ dev_dbg(dev, "crossbar int port #%d - ext port #%d\n", i,
++ (reg >> shift) & mask);
++ }
++}
++
+ static void bcm_sf2_intr_disable(struct bcm_sf2_priv *priv)
+ {
+ intrl2_0_mask_set(priv, 0xffffffff);
+@@ -737,6 +775,8 @@ static int bcm_sf2_sw_resume(struct dsa_
+ return ret;
+ }
+
++ bcm_sf2_crossbar_setup(priv);
++
+ ret = bcm_sf2_cfp_resume(ds);
+ if (ret)
+ return ret;
+@@ -999,6 +1039,7 @@ struct bcm_sf2_of_data {
+ const u16 *reg_offsets;
+ unsigned int core_reg_align;
+ unsigned int num_cfp_rules;
++ unsigned int num_crossbar_int_ports;
+ };
+
+ static const u16 bcm_sf2_4908_reg_offsets[] = {
+@@ -1023,6 +1064,7 @@ static const struct bcm_sf2_of_data bcm_
+ .core_reg_align = 0,
+ .reg_offsets = bcm_sf2_4908_reg_offsets,
+ .num_cfp_rules = 0, /* FIXME */
++ .num_crossbar_int_ports = 2,
+ };
+
+ /* Register offsets for the SWITCH_REG_* block */
+@@ -1133,6 +1175,7 @@ static int bcm_sf2_sw_probe(struct platf
+ priv->reg_offsets = data->reg_offsets;
+ priv->core_reg_align = data->core_reg_align;
+ priv->num_cfp_rules = data->num_cfp_rules;
++ priv->num_crossbar_int_ports = data->num_crossbar_int_ports;
+
+ /* Auto-detection using standard registers will not work, so
+ * provide an indication of what kind of device we are for
+@@ -1187,6 +1230,8 @@ static int bcm_sf2_sw_probe(struct platf
+ return ret;
+ }
+
++ bcm_sf2_crossbar_setup(priv);
++
+ bcm_sf2_gphy_enable_set(priv->dev->ds, true);
+
+ ret = bcm_sf2_mdio_register(ds);
+--- a/drivers/net/dsa/bcm_sf2.h
++++ b/drivers/net/dsa/bcm_sf2.h
+@@ -70,6 +70,7 @@ struct bcm_sf2_priv {
+ const u16 *reg_offsets;
+ unsigned int core_reg_align;
+ unsigned int num_cfp_rules;
++ unsigned int num_crossbar_int_ports;
+
+ /* spinlock protecting access to the indirect registers */
+ spinlock_t indir_lock;
+--- a/drivers/net/dsa/bcm_sf2_regs.h
++++ b/drivers/net/dsa/bcm_sf2_regs.h
+@@ -48,6 +48,13 @@ enum bcm_sf2_reg_offs {
+ #define PHY_PHYAD_SHIFT 8
+ #define PHY_PHYAD_MASK 0x1F
+
++/* Relative to REG_CROSSBAR */
++#define CROSSBAR_BCM4908_INT_P7 0
++#define CROSSBAR_BCM4908_INT_RUNNER 1
++#define CROSSBAR_BCM4908_EXT_SERDES 0
++#define CROSSBAR_BCM4908_EXT_GPHY4 1
++#define CROSSBAR_BCM4908_EXT_RGMII 2
++
+ #define REG_RGMII_CNTRL_P(x) (REG_RGMII_0_CNTRL + (x))
+
+ /* Relative to REG_RGMII_CNTRL */
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1234,10 +1234,14 @@ static int bcm_sf2_sw_probe(struct platf
+@@ -1290,10 +1290,14 @@ static int bcm_sf2_sw_probe(struct platf
rev = reg_readl(priv, REG_PHY_REVISION);
priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1248,6 +1248,12 @@ static int bcm_sf2_sw_probe(struct platf
+@@ -1304,6 +1304,12 @@ static int bcm_sf2_sw_probe(struct platf
priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
priv->irq0, priv->irq1);
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -543,10 +543,19 @@ static void bcm_sf2_sw_mac_config(struct
+@@ -592,10 +592,19 @@ static void bcm_sf2_sw_mac_config(struct
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
u32 id_mode_dis = 0, port_mode;
u32 reg, offset;
if (priv->type == BCM4908_DEVICE_ID ||
priv->type == BCM7445_DEVICE_ID)
offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
-@@ -574,7 +583,7 @@ static void bcm_sf2_sw_mac_config(struct
+@@ -623,7 +632,7 @@ static void bcm_sf2_sw_mac_config(struct
/* Clear id_mode_dis bit, and the existing port mode, let
* RGMII_MODE_EN bet set by mac_link_{up,down}
*/
reg &= ~ID_MODE_DIS;
reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT);
reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN);
-@@ -589,7 +598,7 @@ static void bcm_sf2_sw_mac_config(struct
+@@ -638,7 +647,7 @@ static void bcm_sf2_sw_mac_config(struct
reg |= RX_PAUSE_EN;
}
force_link:
/* Force link settings detected from the PHY */
-@@ -615,6 +624,7 @@ static void bcm_sf2_sw_mac_link_set(stru
+@@ -664,6 +673,7 @@ static void bcm_sf2_sw_mac_link_set(stru
phy_interface_t interface, bool link)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
u32 reg;
if (!phy_interface_mode_is_rgmii(interface) &&
-@@ -622,13 +632,21 @@ static void bcm_sf2_sw_mac_link_set(stru
+@@ -671,13 +681,21 @@ static void bcm_sf2_sw_mac_link_set(stru
interface != PHY_INTERFACE_MODE_REVMII)
return;
}
static void bcm_sf2_sw_mac_link_down(struct dsa_switch *ds, int port,
-@@ -999,9 +1017,7 @@ static const u16 bcm_sf2_4908_reg_offset
+@@ -1051,9 +1069,7 @@ static const u16 bcm_sf2_4908_reg_offset
[REG_PHY_REVISION] = 0x14,
[REG_SPHY_CNTRL] = 0x24,
[REG_CROSSBAR] = 0xc8,