[openwrt/openwrt] bcm4908: backport recent bcm_sf2 changes

LEDE Commits lede-commits at lists.infradead.org
Wed Mar 17 07:11:30 GMT 2021


rmilecki pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/e1b4fd52a8efe1dfcad4f4fbe59f1c35a09be0bd

commit e1b4fd52a8efe1dfcad4f4fbe59f1c35a09be0bd
Author: Rafał Miłecki <rafal at milecki.pl>
AuthorDate: Wed Mar 17 07:40:49 2021 +0100

    bcm4908: backport recent bcm_sf2 changes
    
    One 5.12 link fix and 5.13 crossbar support.
    
    Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 ..._sf2-support-BCM4908-s-integrated-switch.patch} |   0
 ...m_sf2-use-2-Gbps-IMP-port-link-on-BCM4908.patch |  33 +++++
 ..._sf2-store-PHY-interface-mode-in-port-str.patch |  72 ++++++++++
 ...a-bcm_sf2-setup-BCM4908-internal-crossbar.patch | 152 +++++++++++++++++++++
 ...sa-bcm_sf2-enable-GPHY-for-switch-probing.patch |   2 +-
 ...-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch |   2 +-
 ..._sf2-quick-fix-for-RGMII-reg-access-on-BC.patch |  12 +-
 7 files changed, 265 insertions(+), 8 deletions(-)

diff --git a/target/linux/bcm4908/patches-5.4/071-v5.12-0029-net-dsa-bcm_sf2-support-BCM4908-s-integrated-switch.patch b/target/linux/bcm4908/patches-5.4/071-v5.12-0001-net-dsa-bcm_sf2-support-BCM4908-s-integrated-switch.patch
similarity index 100%
rename from target/linux/bcm4908/patches-5.4/071-v5.12-0029-net-dsa-bcm_sf2-support-BCM4908-s-integrated-switch.patch
rename to target/linux/bcm4908/patches-5.4/071-v5.12-0001-net-dsa-bcm_sf2-support-BCM4908-s-integrated-switch.patch
diff --git a/target/linux/bcm4908/patches-5.4/071-v5.12-0002-net-dsa-bcm_sf2-use-2-Gbps-IMP-port-link-on-BCM4908.patch b/target/linux/bcm4908/patches-5.4/071-v5.12-0002-net-dsa-bcm_sf2-use-2-Gbps-IMP-port-link-on-BCM4908.patch
new file mode 100644
index 0000000000..2ab34c1261
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/071-v5.12-0002-net-dsa-bcm_sf2-use-2-Gbps-IMP-port-link-on-BCM4908.patch
@@ -0,0 +1,33 @@
+From 8373a0fe9c7160a55482effa8a3f725efd3f8434 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at 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 at milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: David S. Miller <davem at 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 */
diff --git a/target/linux/bcm4908/patches-5.4/075-v5.13-0001-net-dsa-bcm_sf2-store-PHY-interface-mode-in-port-str.patch b/target/linux/bcm4908/patches-5.4/075-v5.13-0001-net-dsa-bcm_sf2-store-PHY-interface-mode-in-port-str.patch
new file mode 100644
index 0000000000..e9a0b2c79d
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/075-v5.13-0001-net-dsa-bcm_sf2-store-PHY-interface-mode-in-port-str.patch
@@ -0,0 +1,72 @@
+From 01488a0ccd9abe15565bed50a45afcddbb0fe199 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at 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 at milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: David S. Miller <davem at 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;
+ };
+ 
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 at 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 at milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: David S. Miller <davem at 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 */
diff --git a/target/linux/bcm4908/patches-5.4/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch b/target/linux/bcm4908/patches-5.4/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
index 26f6216061..7ba7f73f15 100644
--- a/target/linux/bcm4908/patches-5.4/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
+++ b/target/linux/bcm4908/patches-5.4/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
@@ -29,7 +29,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
 
 --- 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;
  
diff --git a/target/linux/bcm4908/patches-5.4/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch b/target/linux/bcm4908/patches-5.4/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
index 559430a3a7..da5fec8022 100644
--- a/target/linux/bcm4908/patches-5.4/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
+++ b/target/linux/bcm4908/patches-5.4/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
@@ -15,7 +15,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
 
 --- 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);
  
diff --git a/target/linux/bcm4908/patches-5.4/702-net-dsa-bcm_sf2-quick-fix-for-RGMII-reg-access-on-BC.patch b/target/linux/bcm4908/patches-5.4/702-net-dsa-bcm_sf2-quick-fix-for-RGMII-reg-access-on-BC.patch
index 2d88cf353b..49b1ef68a3 100644
--- a/target/linux/bcm4908/patches-5.4/702-net-dsa-bcm_sf2-quick-fix-for-RGMII-reg-access-on-BC.patch
+++ b/target/linux/bcm4908/patches-5.4/702-net-dsa-bcm_sf2-quick-fix-for-RGMII-reg-access-on-BC.patch
@@ -16,7 +16,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
 
 --- 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;
@@ -36,7 +36,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
  	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}
  	 */
@@ -45,7 +45,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
  	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;
  	}
  
@@ -54,7 +54,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
  
  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);
@@ -62,7 +62,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
  	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;
  
@@ -86,7 +86,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
  }
  
  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,



More information about the lede-commits mailing list