netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2 net-next 1/2] net: dsa: bcm_sf2: store PHY interface/mode in port structure
@ 2021-03-12 10:41 Rafał Miłecki
  2021-03-12 10:41 ` [PATCH V2 net-next 2/2] net: dsa: bcm_sf2: setup BCM4908 internal crossbar Rafał Miłecki
  2021-03-12 17:21 ` [PATCH V2 net-next 1/2] net: dsa: bcm_sf2: store PHY interface/mode in port structure Florian Fainelli
  0 siblings, 2 replies; 4+ messages in thread
From: Rafał Miłecki @ 2021-03-12 10:41 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean
  Cc: David S . Miller, Jakub Kicinski, netdev,
	bcm-kernel-feedback-list, Rafał Miłecki

From: Rafał Miłecki <rafal@milecki.pl>

It's needed later for proper switch / crossbar setup.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 drivers/net/dsa/bcm_sf2.c | 16 ++++++++++++----
 drivers/net/dsa/bcm_sf2.h |  1 +
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 4dedd6e0b11b..bc0dbc0daa1a 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -446,10 +446,11 @@ static void bcm_sf2_intr_disable(struct bcm_sf2_priv *priv)
 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;
 	unsigned int port_num;
 	struct property *prop;
-	phy_interface_t mode;
 	int err;
 
 	priv->moca_port = -1;
@@ -458,19 +459,26 @@ static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv,
 		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
 		 */
-		err = of_get_phy_mode(port, &mode);
+		err = of_get_phy_mode(port, &port_st->mode);
 		if (err)
 			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"))
diff --git a/drivers/net/dsa/bcm_sf2.h b/drivers/net/dsa/bcm_sf2.h
index 1ed901a68536..a0fe0bf46d9f 100644
--- a/drivers/net/dsa/bcm_sf2.h
+++ b/drivers/net/dsa/bcm_sf2.h
@@ -44,6 +44,7 @@ struct bcm_sf2_hw_params {
 #define BCM_SF2_REGS_NUM	6
 
 struct bcm_sf2_port_status {
+	phy_interface_t mode;
 	unsigned int link;
 	bool enabled;
 };
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH V2 net-next 2/2] net: dsa: bcm_sf2: setup BCM4908 internal crossbar
  2021-03-12 10:41 [PATCH V2 net-next 1/2] net: dsa: bcm_sf2: store PHY interface/mode in port structure Rafał Miłecki
@ 2021-03-12 10:41 ` Rafał Miłecki
  2021-03-12 17:22   ` Florian Fainelli
  2021-03-12 17:21 ` [PATCH V2 net-next 1/2] net: dsa: bcm_sf2: store PHY interface/mode in port structure Florian Fainelli
  1 sibling, 1 reply; 4+ messages in thread
From: Rafał Miłecki @ 2021-03-12 10:41 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean
  Cc: David S . Miller, Jakub Kicinski, netdev,
	bcm-kernel-feedback-list, Rafał Miłecki

From: Rafał Miłecki <rafal@milecki.pl>

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>
---
V2: Use phy_interface_mode_is_rgmii()
---
 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(+)

diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index bc0dbc0daa1a..28c3cd11520f 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -435,6 +435,44 @@ static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv)
 	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);
@@ -867,6 +905,8 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds)
 		return ret;
 	}
 
+	bcm_sf2_crossbar_setup(priv);
+
 	ret = bcm_sf2_cfp_resume(ds);
 	if (ret)
 		return ret;
@@ -1139,6 +1179,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[] = {
@@ -1163,6 +1204,7 @@ static const struct bcm_sf2_of_data bcm_sf2_4908_data = {
 	.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 */
@@ -1273,6 +1315,7 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
 	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;
 
 	priv->rcdev = devm_reset_control_get_optional_exclusive(&pdev->dev,
 								"switch");
@@ -1346,6 +1389,8 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
 		goto out_clk_mdiv;
 	}
 
+	bcm_sf2_crossbar_setup(priv);
+
 	bcm_sf2_gphy_enable_set(priv->dev->ds, true);
 
 	ret = bcm_sf2_mdio_register(ds);
diff --git a/drivers/net/dsa/bcm_sf2.h b/drivers/net/dsa/bcm_sf2.h
index a0fe0bf46d9f..0d48402068d3 100644
--- a/drivers/net/dsa/bcm_sf2.h
+++ b/drivers/net/dsa/bcm_sf2.h
@@ -74,6 +74,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;
diff --git a/drivers/net/dsa/bcm_sf2_regs.h b/drivers/net/dsa/bcm_sf2_regs.h
index 1d2d55c9f8aa..e297b09411f3 100644
--- 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 */
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH V2 net-next 1/2] net: dsa: bcm_sf2: store PHY interface/mode in port structure
  2021-03-12 10:41 [PATCH V2 net-next 1/2] net: dsa: bcm_sf2: store PHY interface/mode in port structure Rafał Miłecki
  2021-03-12 10:41 ` [PATCH V2 net-next 2/2] net: dsa: bcm_sf2: setup BCM4908 internal crossbar Rafał Miłecki
@ 2021-03-12 17:21 ` Florian Fainelli
  1 sibling, 0 replies; 4+ messages in thread
From: Florian Fainelli @ 2021-03-12 17:21 UTC (permalink / raw)
  To: Rafał Miłecki, Andrew Lunn, Vivien Didelot,
	Florian Fainelli, Vladimir Oltean
  Cc: David S . Miller, Jakub Kicinski, netdev,
	bcm-kernel-feedback-list, Rafał Miłecki

On 3/12/21 2:41 AM, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
> 
> 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>
-- 
Florian

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH V2 net-next 2/2] net: dsa: bcm_sf2: setup BCM4908 internal crossbar
  2021-03-12 10:41 ` [PATCH V2 net-next 2/2] net: dsa: bcm_sf2: setup BCM4908 internal crossbar Rafał Miłecki
@ 2021-03-12 17:22   ` Florian Fainelli
  0 siblings, 0 replies; 4+ messages in thread
From: Florian Fainelli @ 2021-03-12 17:22 UTC (permalink / raw)
  To: Rafał Miłecki, Andrew Lunn, Vivien Didelot,
	Florian Fainelli, Vladimir Oltean
  Cc: David S . Miller, Jakub Kicinski, netdev,
	bcm-kernel-feedback-list, Rafał Miłecki

On 3/12/21 2:41 AM, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
> 
> 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>
-- 
Florian

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-03-12 17:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-12 10:41 [PATCH V2 net-next 1/2] net: dsa: bcm_sf2: store PHY interface/mode in port structure Rafał Miłecki
2021-03-12 10:41 ` [PATCH V2 net-next 2/2] net: dsa: bcm_sf2: setup BCM4908 internal crossbar Rafał Miłecki
2021-03-12 17:22   ` Florian Fainelli
2021-03-12 17:21 ` [PATCH V2 net-next 1/2] net: dsa: bcm_sf2: store PHY interface/mode in port structure Florian Fainelli

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).