diff options
author | Rafał Miłecki <rafal@milecki.pl> | 2021-03-17 07:40:49 +0100 |
---|---|---|
committer | Rafał Miłecki <rafal@milecki.pl> | 2021-03-17 08:10:54 +0100 |
commit | e1b4fd52a8efe1dfcad4f4fbe59f1c35a09be0bd (patch) | |
tree | b59c842510da3355e503028c0a289fcf5ca79774 /target/linux/bcm4908/patches-5.4/075-v5.13-0002-net-dsa-bcm_sf2-setup-BCM4908-internal-crossbar.patch | |
parent | 7091e312307f4563d4a7afb5946140120cfa87fa (diff) | |
download | upstream-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.patch | 152 |
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 */ |