kernel: backport b53/bcm_sf2 changes from v5.7

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
Rafał Miłecki 2022-12-07 09:48:32 +01:00
parent 1f5024aa73
commit 88a71fbe77
23 changed files with 695 additions and 28 deletions

View File

@ -26,7 +26,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/gpio.h>
@@ -2567,8 +2565,9 @@ int b53_switch_detect(struct b53_device
@@ -2596,8 +2594,9 @@ int b53_switch_detect(struct b53_device
dev->chip_id = id32;
break;
default:
@ -38,7 +38,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
return -ENODEV;
}
}
@@ -2598,7 +2597,8 @@ int b53_switch_register(struct b53_devic
@@ -2627,7 +2626,8 @@ int b53_switch_register(struct b53_devic
if (ret)
return ret;

View File

@ -15,7 +15,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -768,8 +768,11 @@ static int b53_switch_reset(struct b53_d
@@ -783,8 +783,11 @@ static int b53_switch_reset(struct b53_d
usleep_range(1000, 2000);
} while (timeout-- > 0);

View File

@ -23,7 +23,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -2363,6 +2363,22 @@ static const struct b53_chip_data b53_sw
@@ -2392,6 +2392,22 @@ static const struct b53_chip_data b53_sw
.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
},
@ -68,7 +68,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
offset = CORE_STS_OVERRIDE_IMP;
else
offset = CORE_STS_OVERRIDE_IMP2;
@@ -555,7 +556,8 @@ static void bcm_sf2_sw_mac_config(struct
@@ -563,7 +564,8 @@ static void bcm_sf2_sw_mac_config(struct
if (port == core_readl(priv, CORE_IMP0_PRT_ID))
return;
@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
else
offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
@@ -1005,6 +1007,30 @@ struct bcm_sf2_of_data {
@@ -1013,6 +1015,30 @@ struct bcm_sf2_of_data {
unsigned int num_cfp_rules;
};
@ -109,7 +109,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* Register offsets for the SWITCH_REG_* block */
static const u16 bcm_sf2_7445_reg_offsets[] = {
[REG_SWITCH_CNTRL] = 0x00,
@@ -1053,6 +1079,9 @@ static const struct bcm_sf2_of_data bcm_
@@ -1061,6 +1087,9 @@ static const struct bcm_sf2_of_data bcm_
};
static const struct of_device_id bcm_sf2_of_match[] = {

View File

@ -18,7 +18,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -392,8 +392,9 @@ static void bcm_sf2_intr_disable(struct
@@ -400,8 +400,9 @@ static void bcm_sf2_intr_disable(struct
static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv,
struct device_node *dn)
{
@ -29,7 +29,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
unsigned int port_num;
priv->moca_port = -1;
@@ -402,19 +403,26 @@ static void bcm_sf2_identify_ports(struc
@@ -410,19 +411,26 @@ static void bcm_sf2_identify_ports(struc
if (of_property_read_u32(port, "reg", &port_num))
continue;

View File

@ -37,7 +37,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -381,6 +381,44 @@ static int bcm_sf2_sw_rst(struct bcm_sf2
@@ -389,6 +389,44 @@ static int bcm_sf2_sw_rst(struct bcm_sf2
return 0;
}
@ -82,7 +82,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
static void bcm_sf2_intr_disable(struct bcm_sf2_priv *priv)
{
intrl2_0_mask_set(priv, 0xffffffff);
@@ -751,6 +789,8 @@ static int bcm_sf2_sw_resume(struct dsa_
@@ -759,6 +797,8 @@ static int bcm_sf2_sw_resume(struct dsa_
return ret;
}
@ -91,7 +91,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
ret = bcm_sf2_cfp_resume(ds);
if (ret)
return ret;
@@ -1016,6 +1056,7 @@ struct bcm_sf2_of_data {
@@ -1024,6 +1064,7 @@ struct bcm_sf2_of_data {
const u16 *reg_offsets;
unsigned int core_reg_align;
unsigned int num_cfp_rules;
@ -99,7 +99,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const u16 bcm_sf2_4908_reg_offsets[] = {
@@ -1040,6 +1081,7 @@ static const struct bcm_sf2_of_data bcm_
@@ -1048,6 +1089,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 */
@ -107,7 +107,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
/* Register offsets for the SWITCH_REG_* block */
@@ -1150,6 +1192,7 @@ static int bcm_sf2_sw_probe(struct platf
@@ -1158,6 +1200,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;
@ -115,7 +115,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
priv->rcdev = devm_reset_control_get_optional_exclusive(&pdev->dev,
"switch");
@@ -1209,6 +1252,8 @@ static int bcm_sf2_sw_probe(struct platf
@@ -1217,6 +1260,8 @@ static int bcm_sf2_sw_probe(struct platf
return ret;
}

View File

@ -14,7 +14,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -1080,7 +1080,7 @@ static const struct bcm_sf2_of_data bcm_
@@ -1088,7 +1088,7 @@ static const struct bcm_sf2_of_data bcm_
.type = BCM4908_DEVICE_ID,
.core_reg_align = 0,
.reg_offsets = bcm_sf2_4908_reg_offsets,

View File

@ -57,7 +57,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
@@ -600,6 +625,7 @@ static void bcm_sf2_sw_mac_config(struct
@@ -608,6 +633,7 @@ 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;
@ -65,7 +65,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
u32 reg, offset;
if (port == core_readl(priv, CORE_IMP0_PRT_ID))
@@ -629,10 +655,12 @@ static void bcm_sf2_sw_mac_config(struct
@@ -637,10 +663,12 @@ static void bcm_sf2_sw_mac_config(struct
goto force_link;
}
@ -79,7 +79,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
reg &= ~ID_MODE_DIS;
reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT);
reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN);
@@ -647,7 +675,7 @@ static void bcm_sf2_sw_mac_config(struct
@@ -655,7 +683,7 @@ static void bcm_sf2_sw_mac_config(struct
reg |= RX_PAUSE_EN;
}
@ -88,7 +88,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
force_link:
/* Force link settings detected from the PHY */
@@ -678,6 +706,7 @@ static void bcm_sf2_sw_mac_link_set(stru
@@ -686,6 +714,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);
@ -96,7 +96,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
u32 reg;
if (!phy_interface_mode_is_rgmii(interface) &&
@@ -685,13 +714,15 @@ static void bcm_sf2_sw_mac_link_set(stru
@@ -693,13 +722,15 @@ static void bcm_sf2_sw_mac_link_set(stru
interface != PHY_INTERFACE_MODE_REVMII)
return;

View File

@ -33,7 +33,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
break;
default:
switch (port) {
@@ -1099,9 +1104,7 @@ static const u16 bcm_sf2_4908_reg_offset
@@ -1107,9 +1112,7 @@ static const u16 bcm_sf2_4908_reg_offset
[REG_PHY_REVISION] = 0x14,
[REG_SPHY_CNTRL] = 0x24,
[REG_CROSSBAR] = 0xc8,

View File

@ -82,7 +82,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
}
}
@@ -1105,9 +1142,14 @@ static const u16 bcm_sf2_4908_reg_offset
@@ -1113,9 +1150,14 @@ static const u16 bcm_sf2_4908_reg_offset
[REG_SPHY_CNTRL] = 0x24,
[REG_CROSSBAR] = 0xc8,
[REG_RGMII_11_CNTRL] = 0x014c,

View File

@ -29,7 +29,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -1388,10 +1388,14 @@ static int bcm_sf2_sw_probe(struct platf
@@ -1396,10 +1396,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;

View File

@ -15,7 +15,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -1402,6 +1402,12 @@ static int bcm_sf2_sw_probe(struct platf
@@ -1410,6 +1410,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);

View File

@ -0,0 +1,37 @@
From 7458bd540fa0a90220b9e8c349d910d9dde9caf8 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Fri, 14 Feb 2020 16:32:29 -0800
Subject: [PATCH] net: dsa: bcm_sf2: Also configure Port 5 for 2Gb/sec on 7278
Either port 5 or port 8 can be used on a 7278 device, make sure that
port 5 also gets configured properly for 2Gb/sec in that case.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/bcm_sf2.c | 3 +++
drivers/net/dsa/bcm_sf2_regs.h | 1 +
2 files changed, 4 insertions(+)
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -620,6 +620,9 @@ force_link:
reg |= RXFLOW_CNTL;
}
+ if (priv->type == BCM7278_DEVICE_ID && dsa_is_cpu_port(ds, port))
+ reg |= GMIIP_SPEED_UP_2G;
+
core_writel(priv, reg, offset);
}
--- a/drivers/net/dsa/bcm_sf2_regs.h
+++ b/drivers/net/dsa/bcm_sf2_regs.h
@@ -178,6 +178,7 @@ enum bcm_sf2_reg_offs {
#define RXFLOW_CNTL (1 << 4)
#define TXFLOW_CNTL (1 << 5)
#define SW_OVERRIDE (1 << 6)
+#define GMIIP_SPEED_UP_2G (1 << 7)
#define CORE_WATCHDOG_CTRL 0x001e4
#define SOFTWARE_RESET (1 << 7)

View File

@ -0,0 +1,43 @@
From 3f02735e5da5367e4cd563ce6e5c21ce27922248 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Mon, 24 Feb 2020 15:44:26 -0800
Subject: [PATCH] Revert "net: dsa: bcm_sf2: Also configure Port 5 for 2Gb/sec
on 7278"
This reverts commit 7458bd540fa0a90220b9e8c349d910d9dde9caf8 ("net: dsa:
bcm_sf2: Also configure Port 5 for 2Gb/sec on 7278") as it causes
advanced congestion buffering issues with 7278 switch devices when using
their internal Giabit PHY. While this is being debugged, continue with
conservative defaults that work and do not cause packet loss.
Fixes: 7458bd540fa0 ("net: dsa: bcm_sf2: Also configure Port 5 for 2Gb/sec on 7278")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Vivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/bcm_sf2.c | 3 ---
drivers/net/dsa/bcm_sf2_regs.h | 1 -
2 files changed, 4 deletions(-)
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -620,9 +620,6 @@ force_link:
reg |= RXFLOW_CNTL;
}
- if (priv->type == BCM7278_DEVICE_ID && dsa_is_cpu_port(ds, port))
- reg |= GMIIP_SPEED_UP_2G;
-
core_writel(priv, reg, offset);
}
--- a/drivers/net/dsa/bcm_sf2_regs.h
+++ b/drivers/net/dsa/bcm_sf2_regs.h
@@ -178,7 +178,6 @@ enum bcm_sf2_reg_offs {
#define RXFLOW_CNTL (1 << 4)
#define TXFLOW_CNTL (1 << 5)
#define SW_OVERRIDE (1 << 6)
-#define GMIIP_SPEED_UP_2G (1 << 7)
#define CORE_WATCHDOG_CTRL 0x001e4
#define SOFTWARE_RESET (1 << 7)

View File

@ -0,0 +1,48 @@
From d7a0b1f7652f9f6b7ba0c9d8ad8edd6b8c0c1511 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Mon, 30 Mar 2020 14:38:47 -0700
Subject: [PATCH] net: dsa: b53: Restore VLAN entries upon (re)configuration
The first time b53_configure_vlan() is called we have not configured any
VLAN entries yet, since that happens later when interfaces get brought
up. When b53_configure_vlan() is called again from suspend/resume we
need to restore all VLAN entries though.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/b53/b53_common.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -696,7 +696,9 @@ int b53_configure_vlan(struct dsa_switch
{
struct b53_device *dev = ds->priv;
struct b53_vlan vl = { 0 };
+ struct b53_vlan *v;
int i, def_vid;
+ u16 vid;
def_vid = b53_default_pvid(dev);
@@ -717,6 +719,19 @@ int b53_configure_vlan(struct dsa_switch
if (!is5325(dev) && !is5365(dev))
b53_set_jumbo(dev, dev->enable_jumbo, false);
+ /* Upon initial call we have not set-up any VLANs, but upon
+ * system resume, we need to restore all VLAN entries.
+ */
+ for (vid = def_vid; vid < dev->num_vlans; vid++) {
+ v = &dev->vlans[vid];
+
+ if (!v->members)
+ continue;
+
+ b53_set_vlan_entry(dev, vid, v);
+ b53_fast_age_vlan(dev, vid);
+ }
+
return 0;
}
EXPORT_SYMBOL(b53_configure_vlan);

View File

@ -0,0 +1,33 @@
From 88631864da093377ce6d5e60b5639328622a8e5c Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Mon, 30 Mar 2020 14:38:48 -0700
Subject: [PATCH] net: dsa: b53: Prevent tagged VLAN on port 7 for 7278
On 7278, port 7 of the switch connects to the ASP UniMAC which is not
capable of processing VLAN tagged frames. We can still allow the port to
be part of a VLAN entry, and we may want it to be untagged on egress on
that VLAN because of that limitation.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/b53/b53_common.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1366,6 +1366,14 @@ int b53_vlan_prepare(struct dsa_switch *
if ((is5325(dev) || is5365(dev)) && vlan->vid_begin == 0)
return -EOPNOTSUPP;
+ /* Port 7 on 7278 connects to the ASP's UniMAC which is not capable of
+ * receiving VLAN tagged frames at all, we can still allow the port to
+ * be configured for egress untagged.
+ */
+ if (dev->chip_id == BCM7278_DEVICE_ID && port == 7 &&
+ !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED))
+ return -EINVAL;
+
if (vlan->vid_end >= dev->num_vlans)
return -ERANGE;

View File

@ -0,0 +1,31 @@
From 31bfc2d42cae6e8b1440fc5db3f0aba6c5d7e602 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Mon, 30 Mar 2020 14:38:49 -0700
Subject: [PATCH] net: dsa: b53: Deny enslaving port 7 for 7278 into a bridge
On 7278, port 7 connects to the ASP which should only receive frames
through the use of CFP rules, it is not desirable to have it be part of
a bridge at all since that would make it pick up unwanted traffic that
it may not even be able to filter or sustain.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/b53/b53_common.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1770,6 +1770,12 @@ int b53_br_join(struct dsa_switch *ds, i
u16 pvlan, reg;
unsigned int i;
+ /* On 7278, port 7 which connects to the ASP should only receive
+ * traffic from matching CFP rules.
+ */
+ if (dev->chip_id == BCM7278_DEVICE_ID && port == 7)
+ return -EINVAL;
+
/* Make this port leave the all VLANs join since we will have proper
* VLAN entries from now on
*/

View File

@ -0,0 +1,36 @@
From 8b6b208b69917d88bb3e087f8c9e61c6b05ed571 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Mon, 30 Mar 2020 14:38:50 -0700
Subject: [PATCH] net: dsa: bcm_sf2: Disable learning for ASP port
We don't want to enable learning for the ASP port since it only receives
directed traffic, this allows us to bypass ARL-driven forwarding rules
which could conflict with Broadcom tags and/or CFP forwarding.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/bcm_sf2.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -173,9 +173,17 @@ static int bcm_sf2_port_setup(struct dsa
core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL);
/* Enable Broadcom tags for that port if requested */
- if (priv->brcm_tag_mask & BIT(port))
+ if (priv->brcm_tag_mask & BIT(port)) {
b53_brcm_hdr_setup(ds, port);
+ /* Disable learning on ASP port */
+ if (port == 7) {
+ reg = core_readl(priv, CORE_DIS_LEARN);
+ reg |= BIT(port);
+ core_writel(priv, reg, CORE_DIS_LEARN);
+ }
+ }
+
/* Configure Traffic Class to QoS mapping, allow each priority to map
* to a different queue number
*/

View File

@ -0,0 +1,33 @@
From 5ae8c0d51ace3bdbfb89c27e7661f081cc9287de Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Mon, 30 Mar 2020 14:38:51 -0700
Subject: [PATCH] net: dsa: bcm_sf2: Check earlier for FLOW_EXT and
FLOW_MAC_EXT
We do not currently support matching on FLOW_EXT or FLOW_MAC_EXT, but we
were not checking for those bits being set in the flow specification.
The check for FLOW_EXT and FLOW_MAC_EXT are separated out because a
subsequent commit will add support for matching VLAN TCI which are
covered by FLOW_EXT.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/bcm_sf2_cfp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/net/dsa/bcm_sf2_cfp.c
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -878,8 +878,9 @@ static int bcm_sf2_cfp_rule_set(struct d
int ret = -EINVAL;
/* Check for unsupported extensions */
- if ((fs->flow_type & FLOW_EXT) && (fs->m_ext.vlan_etype ||
- fs->m_ext.data[1]))
+ if ((fs->flow_type & FLOW_EXT) ||
+ (fs->flow_type & FLOW_MAC_EXT) ||
+ fs->m_ext.data[1])
return -EINVAL;
if (fs->location != RX_CLS_LOC_ANY &&

View File

@ -0,0 +1,131 @@
From c2d639d118d27d6419f5848675ed5c112a86910f Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Mon, 30 Mar 2020 14:38:52 -0700
Subject: [PATCH] net: dsa: bcm_sf2: Move writing of CFP_DATA(5) into slicing
functions
In preparation for matching VLANs, move the writing of CFP_DATA(5) into
the IPv4 and IPv6 slicing logic since they are part of the per-flow
configuration.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/bcm_sf2_cfp.c | 64 +++++++++++++++++------------------
1 file changed, 32 insertions(+), 32 deletions(-)
--- a/drivers/net/dsa/bcm_sf2_cfp.c
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -261,11 +261,20 @@ static int bcm_sf2_cfp_act_pol_set(struc
static void bcm_sf2_cfp_slice_ipv4(struct bcm_sf2_priv *priv,
struct flow_dissector_key_ipv4_addrs *addrs,
struct flow_dissector_key_ports *ports,
- unsigned int slice_num,
+ unsigned int slice_num, u8 num_udf,
bool mask)
{
u32 reg, offset;
+ /* UDF_Valid[7:0] [31:24]
+ * S-Tag [23:8]
+ * C-Tag [7:0]
+ */
+ if (mask)
+ core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_MASK_PORT(5));
+ else
+ core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_DATA_PORT(5));
+
/* C-Tag [31:24]
* UDF_n_A8 [23:8]
* UDF_n_A7 [7:0]
@@ -421,18 +430,11 @@ static int bcm_sf2_cfp_ipv4_rule_set(str
core_writel(priv, layout->udfs[slice_num].mask_value |
udf_upper_bits(num_udf), CORE_CFP_MASK_PORT(6));
- /* UDF_Valid[7:0] [31:24]
- * S-Tag [23:8]
- * C-Tag [7:0]
- */
- core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_DATA_PORT(5));
-
- /* Mask all but valid UDFs */
- core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_MASK_PORT(5));
-
/* Program the match and the mask */
- bcm_sf2_cfp_slice_ipv4(priv, ipv4.key, ports.key, slice_num, false);
- bcm_sf2_cfp_slice_ipv4(priv, ipv4.mask, ports.mask, SLICE_NUM_MASK, true);
+ bcm_sf2_cfp_slice_ipv4(priv, ipv4.key, ports.key, slice_num,
+ num_udf, false);
+ bcm_sf2_cfp_slice_ipv4(priv, ipv4.mask, ports.mask, SLICE_NUM_MASK,
+ num_udf, true);
/* Insert into TCAM now */
bcm_sf2_cfp_rule_addr_set(priv, rule_index);
@@ -468,11 +470,20 @@ out_err_flow_rule:
static void bcm_sf2_cfp_slice_ipv6(struct bcm_sf2_priv *priv,
const __be32 *ip6_addr, const __be16 port,
- unsigned int slice_num,
+ unsigned int slice_num, u32 udf_bits,
bool mask)
{
u32 reg, tmp, val, offset;
+ /* UDF_Valid[7:0] [31:24]
+ * S-Tag [23:8]
+ * C-Tag [7:0]
+ */
+ if (mask)
+ core_writel(priv, udf_bits << 24, CORE_CFP_MASK_PORT(5));
+ else
+ core_writel(priv, udf_bits << 24, CORE_CFP_DATA_PORT(5));
+
/* C-Tag [31:24]
* UDF_n_B8 [23:8] (port)
* UDF_n_B7 (upper) [7:0] (addr[15:8])
@@ -704,20 +715,13 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
reg = layout->udfs[slice_num].mask_value | udf_upper_bits(num_udf);
core_writel(priv, reg, CORE_CFP_MASK_PORT(6));
- /* UDF_Valid[7:0] [31:24]
- * S-Tag [23:8]
- * C-Tag [7:0]
- */
- core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_DATA_PORT(5));
-
- /* Mask all but valid UDFs */
- core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_MASK_PORT(5));
-
/* Slice the IPv6 source address and port */
bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->src.in6_u.u6_addr32,
- ports.key->src, slice_num, false);
+ ports.key->src, slice_num,
+ udf_lower_bits(num_udf), false);
bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->src.in6_u.u6_addr32,
- ports.mask->src, SLICE_NUM_MASK, true);
+ ports.mask->src, SLICE_NUM_MASK,
+ udf_lower_bits(num_udf), true);
/* Insert into TCAM now because we need to insert a second rule */
bcm_sf2_cfp_rule_addr_set(priv, rule_index[0]);
@@ -768,16 +772,12 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
udf_lower_bits(num_udf) << 8;
core_writel(priv, reg, CORE_CFP_MASK_PORT(6));
- /* Don't care */
- core_writel(priv, 0, CORE_CFP_DATA_PORT(5));
-
- /* Mask all */
- core_writel(priv, 0, CORE_CFP_MASK_PORT(5));
-
bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->dst.in6_u.u6_addr32,
- ports.key->dst, slice_num, false);
+ ports.key->dst, slice_num,
+ 0, false);
bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->dst.in6_u.u6_addr32,
- ports.key->dst, SLICE_NUM_MASK, true);
+ ports.key->dst, SLICE_NUM_MASK,
+ 0, true);
/* Insert into TCAM now */
bcm_sf2_cfp_rule_addr_set(priv, rule_index[1]);

View File

@ -0,0 +1,181 @@
From 7555020c44db75a0d934dffc0aa6c678b52b2a13 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Mon, 30 Mar 2020 14:38:53 -0700
Subject: [PATCH] net: dsa: bcm_sf2: Add support for matching VLAN TCI
Update relevant code paths to support the programming and matching of
VLAN TCI, this is the only member of the ethtool_flow_ext that we can
match, the switch does not permit matching the VLAN Ethernet Type field.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/bcm_sf2_cfp.c | 53 +++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 15 deletions(-)
--- a/drivers/net/dsa/bcm_sf2_cfp.c
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -261,6 +261,7 @@ static int bcm_sf2_cfp_act_pol_set(struc
static void bcm_sf2_cfp_slice_ipv4(struct bcm_sf2_priv *priv,
struct flow_dissector_key_ipv4_addrs *addrs,
struct flow_dissector_key_ports *ports,
+ const __be16 vlan_tci,
unsigned int slice_num, u8 num_udf,
bool mask)
{
@@ -270,16 +271,17 @@ static void bcm_sf2_cfp_slice_ipv4(struc
* S-Tag [23:8]
* C-Tag [7:0]
*/
+ reg = udf_lower_bits(num_udf) << 24 | be16_to_cpu(vlan_tci) >> 8;
if (mask)
- core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_MASK_PORT(5));
+ core_writel(priv, reg, CORE_CFP_MASK_PORT(5));
else
- core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_DATA_PORT(5));
+ core_writel(priv, reg, CORE_CFP_DATA_PORT(5));
/* C-Tag [31:24]
* UDF_n_A8 [23:8]
* UDF_n_A7 [7:0]
*/
- reg = 0;
+ reg = (u32)(be16_to_cpu(vlan_tci) & 0xff) << 24;
if (mask)
offset = CORE_CFP_MASK_PORT(4);
else
@@ -345,6 +347,7 @@ static int bcm_sf2_cfp_ipv4_rule_set(str
struct ethtool_rx_flow_spec *fs)
{
struct ethtool_rx_flow_spec_input input = {};
+ __be16 vlan_tci = 0 , vlan_m_tci = 0xffff;
const struct cfp_udf_layout *layout;
unsigned int slice_num, rule_index;
struct ethtool_rx_flow_rule *flow;
@@ -369,6 +372,12 @@ static int bcm_sf2_cfp_ipv4_rule_set(str
ip_frag = !!(be32_to_cpu(fs->h_ext.data[0]) & 1);
+ /* Extract VLAN TCI */
+ if (fs->flow_type & FLOW_EXT) {
+ vlan_tci = fs->h_ext.vlan_tci;
+ vlan_m_tci = fs->m_ext.vlan_tci;
+ }
+
/* Locate the first rule available */
if (fs->location == RX_CLS_LOC_ANY)
rule_index = find_first_zero_bit(priv->cfp.used,
@@ -431,10 +440,10 @@ static int bcm_sf2_cfp_ipv4_rule_set(str
udf_upper_bits(num_udf), CORE_CFP_MASK_PORT(6));
/* Program the match and the mask */
- bcm_sf2_cfp_slice_ipv4(priv, ipv4.key, ports.key, slice_num,
- num_udf, false);
- bcm_sf2_cfp_slice_ipv4(priv, ipv4.mask, ports.mask, SLICE_NUM_MASK,
- num_udf, true);
+ bcm_sf2_cfp_slice_ipv4(priv, ipv4.key, ports.key, vlan_tci,
+ slice_num, num_udf, false);
+ bcm_sf2_cfp_slice_ipv4(priv, ipv4.mask, ports.mask, vlan_m_tci,
+ SLICE_NUM_MASK, num_udf, true);
/* Insert into TCAM now */
bcm_sf2_cfp_rule_addr_set(priv, rule_index);
@@ -470,6 +479,7 @@ out_err_flow_rule:
static void bcm_sf2_cfp_slice_ipv6(struct bcm_sf2_priv *priv,
const __be32 *ip6_addr, const __be16 port,
+ const __be16 vlan_tci,
unsigned int slice_num, u32 udf_bits,
bool mask)
{
@@ -479,10 +489,11 @@ static void bcm_sf2_cfp_slice_ipv6(struc
* S-Tag [23:8]
* C-Tag [7:0]
*/
+ reg = udf_bits << 24 | be16_to_cpu(vlan_tci) >> 8;
if (mask)
- core_writel(priv, udf_bits << 24, CORE_CFP_MASK_PORT(5));
+ core_writel(priv, reg, CORE_CFP_MASK_PORT(5));
else
- core_writel(priv, udf_bits << 24, CORE_CFP_DATA_PORT(5));
+ core_writel(priv, reg, CORE_CFP_DATA_PORT(5));
/* C-Tag [31:24]
* UDF_n_B8 [23:8] (port)
@@ -490,6 +501,7 @@ static void bcm_sf2_cfp_slice_ipv6(struc
*/
reg = be32_to_cpu(ip6_addr[3]);
val = (u32)be16_to_cpu(port) << 8 | ((reg >> 8) & 0xff);
+ val |= (u32)(be16_to_cpu(vlan_tci) & 0xff) << 24;
if (mask)
offset = CORE_CFP_MASK_PORT(4);
else
@@ -598,6 +610,11 @@ static int bcm_sf2_cfp_rule_cmp(struct b
ret = memcmp(&rule->fs.h_u, &fs->h_u, fs_size);
ret |= memcmp(&rule->fs.m_u, &fs->m_u, fs_size);
+ /* Compare VLAN TCI values as well */
+ if (rule->fs.flow_type & FLOW_EXT) {
+ ret |= rule->fs.h_ext.vlan_tci != fs->h_ext.vlan_tci;
+ ret |= rule->fs.m_ext.vlan_tci != fs->m_ext.vlan_tci;
+ }
if (ret == 0)
break;
}
@@ -611,6 +628,7 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
struct ethtool_rx_flow_spec *fs)
{
struct ethtool_rx_flow_spec_input input = {};
+ __be16 vlan_tci = 0, vlan_m_tci = 0xffff;
unsigned int slice_num, rule_index[2];
const struct cfp_udf_layout *layout;
struct ethtool_rx_flow_rule *flow;
@@ -634,6 +652,12 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
ip_frag = !!(be32_to_cpu(fs->h_ext.data[0]) & 1);
+ /* Extract VLAN TCI */
+ if (fs->flow_type & FLOW_EXT) {
+ vlan_tci = fs->h_ext.vlan_tci;
+ vlan_m_tci = fs->m_ext.vlan_tci;
+ }
+
layout = &udf_tcpip6_layout;
slice_num = bcm_sf2_get_slice_number(layout, 0);
if (slice_num == UDF_NUM_SLICES)
@@ -717,10 +741,10 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
/* Slice the IPv6 source address and port */
bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->src.in6_u.u6_addr32,
- ports.key->src, slice_num,
+ ports.key->src, vlan_tci, slice_num,
udf_lower_bits(num_udf), false);
bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->src.in6_u.u6_addr32,
- ports.mask->src, SLICE_NUM_MASK,
+ ports.mask->src, vlan_m_tci, SLICE_NUM_MASK,
udf_lower_bits(num_udf), true);
/* Insert into TCAM now because we need to insert a second rule */
@@ -773,10 +797,10 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
core_writel(priv, reg, CORE_CFP_MASK_PORT(6));
bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->dst.in6_u.u6_addr32,
- ports.key->dst, slice_num,
+ ports.key->dst, 0, slice_num,
0, false);
bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->dst.in6_u.u6_addr32,
- ports.key->dst, SLICE_NUM_MASK,
+ ports.key->dst, 0, SLICE_NUM_MASK,
0, true);
/* Insert into TCAM now */
@@ -878,8 +902,7 @@ static int bcm_sf2_cfp_rule_set(struct d
int ret = -EINVAL;
/* Check for unsupported extensions */
- if ((fs->flow_type & FLOW_EXT) ||
- (fs->flow_type & FLOW_MAC_EXT) ||
+ if ((fs->flow_type & FLOW_MAC_EXT) ||
fs->m_ext.data[1])
return -EINVAL;

View File

@ -0,0 +1,94 @@
From 8b3abe304c5f1057b7bac70fd5576dfa67e3e2b3 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Mon, 30 Mar 2020 14:38:54 -0700
Subject: [PATCH] net: dsa: bcm_sf2: Support specifying VLAN tag egress rule
The port to which the ASP is connected on 7278 is not capable of
processing VLAN tags as part of the Ethernet frame, so allow an user to
configure the egress VLAN policy they want to see applied by purposing
the h_ext.data[1] field. Bit 0 is used to indicate that 0=tagged,
1=untagged.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/bcm_sf2_cfp.c | 40 +++++++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)
--- a/drivers/net/dsa/bcm_sf2_cfp.c
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -13,6 +13,8 @@
#include <net/dsa.h>
#include <linux/bitmap.h>
#include <net/flow_offload.h>
+#include <net/switchdev.h>
+#include <uapi/linux/if_bridge.h>
#include "bcm_sf2.h"
#include "bcm_sf2_regs.h"
@@ -847,7 +849,9 @@ static int bcm_sf2_cfp_rule_insert(struc
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
s8 cpu_port = ds->ports[port].cpu_dp->index;
__u64 ring_cookie = fs->ring_cookie;
+ struct switchdev_obj_port_vlan vlan;
unsigned int queue_num, port_num;
+ u16 vid;
int ret;
/* This rule is a Wake-on-LAN filter and we must specifically
@@ -867,6 +871,34 @@ static int bcm_sf2_cfp_rule_insert(struc
dsa_is_cpu_port(ds, port_num)) ||
port_num >= priv->hw_params.num_ports)
return -EINVAL;
+
+ /* If the rule is matching a particular VLAN, make sure that we honor
+ * the matching and have it tagged or untagged on the destination port,
+ * we do this on egress with a VLAN entry. The egress tagging attribute
+ * is expected to be provided in h_ext.data[1] bit 0. A 1 means untagged,
+ * a 0 means tagged.
+ */
+ if (fs->flow_type & FLOW_EXT) {
+ /* We cannot support matching multiple VLAN IDs yet */
+ if ((be16_to_cpu(fs->m_ext.vlan_tci) & VLAN_VID_MASK) !=
+ VLAN_VID_MASK)
+ return -EINVAL;
+
+ vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK;
+ vlan.vid_begin = vid;
+ vlan.vid_end = vid;
+ if (cpu_to_be32(fs->h_ext.data[1]) & 1)
+ vlan.flags = BRIDGE_VLAN_INFO_UNTAGGED;
+ else
+ vlan.flags = 0;
+
+ ret = ds->ops->port_vlan_prepare(ds, port_num, &vlan);
+ if (ret)
+ return ret;
+
+ ds->ops->port_vlan_add(ds, port_num, &vlan);
+ }
+
/*
* We have a small oddity where Port 6 just does not have a
* valid bit here (so we substract by one).
@@ -902,14 +934,18 @@ static int bcm_sf2_cfp_rule_set(struct d
int ret = -EINVAL;
/* Check for unsupported extensions */
- if ((fs->flow_type & FLOW_MAC_EXT) ||
- fs->m_ext.data[1])
+ if (fs->flow_type & FLOW_MAC_EXT)
return -EINVAL;
if (fs->location != RX_CLS_LOC_ANY &&
fs->location > bcm_sf2_cfp_rule_size(priv))
return -EINVAL;
+ if ((fs->flow_type & FLOW_EXT) &&
+ !(ds->ops->port_vlan_prepare || ds->ops->port_vlan_add ||
+ ds->ops->port_vlan_del))
+ return -EOPNOTSUPP;
+
if (fs->location != RX_CLS_LOC_ANY &&
test_bit(fs->location, priv->cfp.used))
return -EBUSY;

View File

@ -20,7 +20,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1577,7 +1577,6 @@ static int b53_arl_op(struct b53_device
@@ -1600,7 +1600,6 @@ static int b53_arl_op(struct b53_device
ent.is_valid = !!(ent.port);
}

View File

@ -12,7 +12,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1297,7 +1297,9 @@ EXPORT_SYMBOL(b53_phylink_mac_link_down)
@@ -1312,7 +1312,9 @@ EXPORT_SYMBOL(b53_phylink_mac_link_down)
void b53_phylink_mac_link_up(struct dsa_switch *ds, int port,
unsigned int mode,
phy_interface_t interface,
@ -38,7 +38,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
const struct switchdev_obj_port_vlan *vlan);
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -653,7 +653,9 @@ static void bcm_sf2_sw_mac_link_down(str
@@ -661,7 +661,9 @@ static void bcm_sf2_sw_mac_link_down(str
static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port,
unsigned int mode,
phy_interface_t interface,