aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm4908/patches-5.4/075-v5.13-0002-net-dsa-bcm_sf2-setup-BCM4908-internal-crossbar.patch
diff options
context:
space:
mode:
authorRafał Miłecki <rafal@milecki.pl>2021-03-17 07:40:49 +0100
committerRafał Miłecki <rafal@milecki.pl>2021-03-17 08:10:54 +0100
commite1b4fd52a8efe1dfcad4f4fbe59f1c35a09be0bd (patch)
treeb59c842510da3355e503028c0a289fcf5ca79774 /target/linux/bcm4908/patches-5.4/075-v5.13-0002-net-dsa-bcm_sf2-setup-BCM4908-internal-crossbar.patch
parent7091e312307f4563d4a7afb5946140120cfa87fa (diff)
downloadupstream-e1b4fd52a8efe1dfcad4f4fbe59f1c35a09be0bd.tar.gz
upstream-e1b4fd52a8efe1dfcad4f4fbe59f1c35a09be0bd.tar.bz2
upstream-e1b4fd52a8efe1dfcad4f4fbe59f1c35a09be0bd.zip
bcm4908: backport recent bcm_sf2 changes
One 5.12 link fix and 5.13 crossbar support. Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Diffstat (limited to 'target/linux/bcm4908/patches-5.4/075-v5.13-0002-net-dsa-bcm_sf2-setup-BCM4908-internal-crossbar.patch')
-rw-r--r--target/linux/bcm4908/patches-5.4/075-v5.13-0002-net-dsa-bcm_sf2-setup-BCM4908-internal-crossbar.patch152
1 files changed, 152 insertions, 0 deletions
diff --git a/target/linux/bcm4908/patches-5.4/075-v5.13-0002-net-dsa-bcm_sf2-setup-BCM4908-internal-crossbar.patch b/target/linux/bcm4908/patches-5.4/075-v5.13-0002-net-dsa-bcm_sf2-setup-BCM4908-internal-crossbar.patch
new file mode 100644
index 0000000000..cd49ec1ab8
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/075-v5.13-0002-net-dsa-bcm_sf2-setup-BCM4908-internal-crossbar.patch
@@ -0,0 +1,152 @@
+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 */