mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-04 21:14:21 +00:00
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>
(cherry picked from commit e1b4fd52a8
)
This commit is contained in:
parent
86eb3de66e
commit
15d142262a
@ -0,0 +1,33 @@
|
|||||||
|
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 */
|
@ -0,0 +1,72 @@
|
|||||||
|
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;
|
||||||
|
};
|
||||||
|
|
@ -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 */
|
@ -29,7 +29,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
|
|
||||||
--- a/drivers/net/dsa/bcm_sf2.c
|
--- a/drivers/net/dsa/bcm_sf2.c
|
||||||
+++ b/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);
|
rev = reg_readl(priv, REG_PHY_REVISION);
|
||||||
priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
|
priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
|
|
||||||
--- a/drivers/net/dsa/bcm_sf2.c
|
--- a/drivers/net/dsa/bcm_sf2.c
|
||||||
+++ b/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->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
|
||||||
priv->irq0, priv->irq1);
|
priv->irq0, priv->irq1);
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
|
|
||||||
--- a/drivers/net/dsa/bcm_sf2.c
|
--- a/drivers/net/dsa/bcm_sf2.c
|
||||||
+++ b/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);
|
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
|
||||||
u32 id_mode_dis = 0, port_mode;
|
u32 id_mode_dis = 0, port_mode;
|
||||||
u32 reg, offset;
|
u32 reg, offset;
|
||||||
@ -36,7 +36,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
if (priv->type == BCM4908_DEVICE_ID ||
|
if (priv->type == BCM4908_DEVICE_ID ||
|
||||||
priv->type == BCM7445_DEVICE_ID)
|
priv->type == BCM7445_DEVICE_ID)
|
||||||
offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
|
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
|
/* Clear id_mode_dis bit, and the existing port mode, let
|
||||||
* RGMII_MODE_EN bet set by mac_link_{up,down}
|
* RGMII_MODE_EN bet set by mac_link_{up,down}
|
||||||
*/
|
*/
|
||||||
@ -45,7 +45,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
reg &= ~ID_MODE_DIS;
|
reg &= ~ID_MODE_DIS;
|
||||||
reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT);
|
reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT);
|
||||||
reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN);
|
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;
|
reg |= RX_PAUSE_EN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
|
|
||||||
force_link:
|
force_link:
|
||||||
/* Force link settings detected from the PHY */
|
/* 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)
|
phy_interface_t interface, bool link)
|
||||||
{
|
{
|
||||||
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
|
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
|
||||||
@ -62,7 +62,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
if (!phy_interface_mode_is_rgmii(interface) &&
|
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)
|
interface != PHY_INTERFACE_MODE_REVMII)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bcm_sf2_sw_mac_link_down(struct dsa_switch *ds, int port,
|
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_PHY_REVISION] = 0x14,
|
||||||
[REG_SPHY_CNTRL] = 0x24,
|
[REG_SPHY_CNTRL] = 0x24,
|
||||||
[REG_CROSSBAR] = 0xc8,
|
[REG_CROSSBAR] = 0xc8,
|
||||||
|
Loading…
Reference in New Issue
Block a user