netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278
@ 2020-03-30 20:40 Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 1/9] net: dsa: bcm_sf2: Fix overflow checks Florian Fainelli
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, andrew, vivien.didelot, davem, kuba, dan.carpenter

Hi David, Andrew, Vivien,

This patch series contains some updates to the b53 and bcm_sf2 drivers
specifically for the 7278 Ethernet switch.

The first patch is technically a bug fix so it should ideally be
backported to -stable, provided that Dan also agress with my resolution
on this.

Patches #2 through #4 are minor changes to the core b53 driver to
restore VLAN configuration upon system resumption as well as deny
specific bridge/VLAN operations on port 7 with the 7278 which is special
and does not support VLANs.

Patches #5 through #9 add support for matching VLAN TCI keys/masks to
the CFP code.

Florian Fainelli (9):
  net: dsa: bcm_sf2: Fix overflow checks
  net: dsa: b53: Restore VLAN entries upon (re)configuration
  net: dsa: b53: Prevent tagged VLAN on port 7 for 7278
  net: dsa: b53: Deny enslaving port 7 for 7278 into a bridge
  net: dsa: bcm_sf2: Disable learning for ASP port
  net: dsa: bcm_sf2: Check earlier for FLOW_EXT and FLOW_MAC_EXT
  net: dsa: bcm_sf2: Move writing of CFP_DATA(5) into slicing functions
  net: dsa: bcm_sf2: Add support for matching VLAN TCI
  net: dsa: bcm_sf2: Support specifying VLAN tag egress rule

 drivers/net/dsa/b53/b53_common.c |  29 +++++++
 drivers/net/dsa/bcm_sf2.c        |  10 ++-
 drivers/net/dsa/bcm_sf2_cfp.c    | 139 ++++++++++++++++++++++---------
 3 files changed, 136 insertions(+), 42 deletions(-)

-- 
2.17.1


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

* [PATCH net-next 1/9] net: dsa: bcm_sf2: Fix overflow checks
  2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
@ 2020-03-30 20:40 ` Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 2/9] net: dsa: b53: Restore VLAN entries upon (re)configuration Florian Fainelli
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, andrew, vivien.didelot, davem, kuba, dan.carpenter

Commit f949a12fd697 ("net: dsa: bcm_sf2: fix buffer overflow doing
set_rxnfc") tried to fix the some user controlled buffer overflows in
bcm_sf2_cfp_rule_set() and bcm_sf2_cfp_rule_del() but the fix was using
CFP_NUM_RULES, which while it is correct not to overflow the bitmaps, is
not representative of what the device actually supports. Correct that by
using bcm_sf2_cfp_rule_size() instead.

The latter subtracts the number of rules by 1, so change the checks from
greater than or equal to greater than accordingly.

Fixes: f949a12fd697 ("net: dsa: bcm_sf2: fix buffer overflow doing set_rxnfc")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/dsa/bcm_sf2_cfp.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c
index 1962c8330daa..f9785027c096 100644
--- a/drivers/net/dsa/bcm_sf2_cfp.c
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -882,17 +882,14 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
 	     fs->m_ext.data[1]))
 		return -EINVAL;
 
-	if (fs->location != RX_CLS_LOC_ANY && fs->location >= CFP_NUM_RULES)
+	if (fs->location != RX_CLS_LOC_ANY &&
+	    fs->location > bcm_sf2_cfp_rule_size(priv))
 		return -EINVAL;
 
 	if (fs->location != RX_CLS_LOC_ANY &&
 	    test_bit(fs->location, priv->cfp.used))
 		return -EBUSY;
 
-	if (fs->location != RX_CLS_LOC_ANY &&
-	    fs->location > bcm_sf2_cfp_rule_size(priv))
-		return -EINVAL;
-
 	ret = bcm_sf2_cfp_rule_cmp(priv, port, fs);
 	if (ret == 0)
 		return -EEXIST;
@@ -973,7 +970,7 @@ static int bcm_sf2_cfp_rule_del(struct bcm_sf2_priv *priv, int port, u32 loc)
 	struct cfp_rule *rule;
 	int ret;
 
-	if (loc >= CFP_NUM_RULES)
+	if (loc > bcm_sf2_cfp_rule_size(priv))
 		return -EINVAL;
 
 	/* Refuse deleting unused rules, and those that are not unique since
-- 
2.17.1


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

* [PATCH net-next 2/9] net: dsa: b53: Restore VLAN entries upon (re)configuration
  2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 1/9] net: dsa: bcm_sf2: Fix overflow checks Florian Fainelli
@ 2020-03-30 20:40 ` Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 3/9] net: dsa: b53: Prevent tagged VLAN on port 7 for 7278 Florian Fainelli
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, andrew, vivien.didelot, davem, kuba, dan.carpenter

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>
---
 drivers/net/dsa/b53/b53_common.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 39ae4ed87d1d..5cb678e8b9cd 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -681,7 +681,9 @@ int b53_configure_vlan(struct dsa_switch *ds)
 {
 	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);
 
@@ -699,6 +701,19 @@ int b53_configure_vlan(struct dsa_switch *ds)
 		b53_write16(dev, B53_VLAN_PAGE,
 			    B53_VLAN_PORT_DEF_TAG(i), def_vid);
 
+	/* 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);
-- 
2.17.1


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

* [PATCH net-next 3/9] net: dsa: b53: Prevent tagged VLAN on port 7 for 7278
  2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 1/9] net: dsa: bcm_sf2: Fix overflow checks Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 2/9] net: dsa: b53: Restore VLAN entries upon (re)configuration Florian Fainelli
@ 2020-03-30 20:40 ` Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 4/9] net: dsa: b53: Deny enslaving port 7 for 7278 into a bridge Florian Fainelli
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, andrew, vivien.didelot, davem, kuba, dan.carpenter

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, 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>
---
 drivers/net/dsa/b53/b53_common.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 5cb678e8b9cd..42c41b091682 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1355,6 +1355,14 @@ int b53_vlan_prepare(struct dsa_switch *ds, int port,
 	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;
 
-- 
2.17.1


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

* [PATCH net-next 4/9] net: dsa: b53: Deny enslaving port 7 for 7278 into a bridge
  2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
                   ` (2 preceding siblings ...)
  2020-03-30 20:40 ` [PATCH net-next 3/9] net: dsa: b53: Prevent tagged VLAN on port 7 for 7278 Florian Fainelli
@ 2020-03-30 20:40 ` Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 5/9] net: dsa: bcm_sf2: Disable learning for ASP port Florian Fainelli
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, andrew, vivien.didelot, davem, kuba, dan.carpenter

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>
---
 drivers/net/dsa/b53/b53_common.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 42c41b091682..68e2381694b9 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1728,6 +1728,12 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
 	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
 	 */
-- 
2.17.1


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

* [PATCH net-next 5/9] net: dsa: bcm_sf2: Disable learning for ASP port
  2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
                   ` (3 preceding siblings ...)
  2020-03-30 20:40 ` [PATCH net-next 4/9] net: dsa: b53: Deny enslaving port 7 for 7278 into a bridge Florian Fainelli
@ 2020-03-30 20:40 ` Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 6/9] net: dsa: bcm_sf2: Check earlier for FLOW_EXT and FLOW_MAC_EXT Florian Fainelli
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, andrew, vivien.didelot, davem, kuba, dan.carpenter

We don't want to enable learning for the ASP port since it just received
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>
---
 drivers/net/dsa/bcm_sf2.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 368ead87e07a..affa5c6e135c 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -178,9 +178,17 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
 	core_writel(priv, reg, CORE_DIS_LEARN);
 
 	/* 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
 	 */
-- 
2.17.1


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

* [PATCH net-next 6/9] net: dsa: bcm_sf2: Check earlier for FLOW_EXT and FLOW_MAC_EXT
  2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
                   ` (4 preceding siblings ...)
  2020-03-30 20:40 ` [PATCH net-next 5/9] net: dsa: bcm_sf2: Disable learning for ASP port Florian Fainelli
@ 2020-03-30 20:40 ` Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 7/9] net: dsa: bcm_sf2: Move writing of CFP_DATA(5) into slicing functions Florian Fainelli
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, andrew, vivien.didelot, davem, kuba, dan.carpenter

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.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/dsa/bcm_sf2_cfp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c
index f9785027c096..6e26a9083d32 100644
--- a/drivers/net/dsa/bcm_sf2_cfp.c
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -878,8 +878,8 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
 	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 || FLOW_MAC_EXT)) ||
+	    fs->m_ext.data[1])
 		return -EINVAL;
 
 	if (fs->location != RX_CLS_LOC_ANY &&
-- 
2.17.1


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

* [PATCH net-next 7/9] net: dsa: bcm_sf2: Move writing of CFP_DATA(5) into slicing functions
  2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
                   ` (5 preceding siblings ...)
  2020-03-30 20:40 ` [PATCH net-next 6/9] net: dsa: bcm_sf2: Check earlier for FLOW_EXT and FLOW_MAC_EXT Florian Fainelli
@ 2020-03-30 20:40 ` Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 8/9] net: dsa: bcm_sf2: Add support for matching VLAN TCI Florian Fainelli
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, andrew, vivien.didelot, davem, kuba, dan.carpenter

In preparation for matching VLANs, move the writing of CFP_DATA(5) into
the IPv4 and IPv6 slicing since they are part of the per-flow
configuration.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/dsa/bcm_sf2_cfp.c | 64 +++++++++++++++++------------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c
index 6e26a9083d32..8529f55a4d1f 100644
--- 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(struct bcm_sf2_priv *priv,
 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(struct bcm_sf2_priv *priv, int port,
 	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 @@ static int bcm_sf2_cfp_ipv4_rule_set(struct bcm_sf2_priv *priv, int port,
 
 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(struct bcm_sf2_priv *priv, int port,
 	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(struct bcm_sf2_priv *priv, int port,
 		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]);
-- 
2.17.1


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

* [PATCH net-next 8/9] net: dsa: bcm_sf2: Add support for matching VLAN TCI
  2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
                   ` (6 preceding siblings ...)
  2020-03-30 20:40 ` [PATCH net-next 7/9] net: dsa: bcm_sf2: Move writing of CFP_DATA(5) into slicing functions Florian Fainelli
@ 2020-03-30 20:40 ` Florian Fainelli
  2020-03-30 20:40 ` [PATCH net-next 9/9] net: dsa: bcm_sf2: Support specifying VLAN tag egress rule Florian Fainelli
  2020-03-30 20:53 ` [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
  9 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, andrew, vivien.didelot, davem, kuba, dan.carpenter

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>
---
 drivers/net/dsa/bcm_sf2_cfp.c | 52 +++++++++++++++++++++++++----------
 1 file changed, 38 insertions(+), 14 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c
index 8529f55a4d1f..7b10a9f31538 100644
--- 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(struct bcm_sf2_priv *priv,
 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(struct bcm_sf2_priv *priv,
 	 * 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(struct bcm_sf2_priv *priv, int port,
 				     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(struct bcm_sf2_priv *priv, int port,
 
 	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(struct bcm_sf2_priv *priv, int port,
 		    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 @@ static int bcm_sf2_cfp_ipv4_rule_set(struct bcm_sf2_priv *priv, int port,
 
 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(struct bcm_sf2_priv *priv,
 	 * 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(struct bcm_sf2_priv *priv,
 	 */
 	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 bcm_sf2_priv *priv, int port,
 
 		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(struct bcm_sf2_priv *priv, int port,
 				     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(struct bcm_sf2_priv *priv, int port,
 
 	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(struct bcm_sf2_priv *priv, int port,
 
 	/* 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(struct bcm_sf2_priv *priv, int port,
 	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,7 +902,7 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
 	int ret = -EINVAL;
 
 	/* Check for unsupported extensions */
-	if ((fs->flow_type & (FLOW_EXT || FLOW_MAC_EXT)) ||
+	if ((fs->flow_type & FLOW_MAC_EXT) ||
 	    fs->m_ext.data[1])
 		return -EINVAL;
 
-- 
2.17.1


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

* [PATCH net-next 9/9] net: dsa: bcm_sf2: Support specifying VLAN tag egress rule
  2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
                   ` (7 preceding siblings ...)
  2020-03-30 20:40 ` [PATCH net-next 8/9] net: dsa: bcm_sf2: Add support for matching VLAN TCI Florian Fainelli
@ 2020-03-30 20:40 ` Florian Fainelli
  2020-03-30 20:53 ` [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
  9 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, andrew, vivien.didelot, davem, kuba, dan.carpenter

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=untagged,
1=tagged.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/dsa/bcm_sf2_cfp.c | 40 +++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c
index 7b10a9f31538..1a26232ecd47 100644
--- 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(struct dsa_switch *ds, int port,
 	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
 	s8 cpu_port = dsa_to_port(ds, 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(struct dsa_switch *ds, int port,
 	      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 tagged,
+	 * a 0 means untagged.
+	 */
+	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 dsa_switch *ds, int port,
 	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;
-- 
2.17.1


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

* Re: [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278
  2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
                   ` (8 preceding siblings ...)
  2020-03-30 20:40 ` [PATCH net-next 9/9] net: dsa: bcm_sf2: Support specifying VLAN tag egress rule Florian Fainelli
@ 2020-03-30 20:53 ` Florian Fainelli
  9 siblings, 0 replies; 11+ messages in thread
From: Florian Fainelli @ 2020-03-30 20:53 UTC (permalink / raw)
  To: netdev; +Cc: andrew, vivien.didelot, davem, kuba, dan.carpenter

Hi David,

On 3/30/2020 1:40 PM, Florian Fainelli wrote:
> Hi David, Andrew, Vivien,
> 
> This patch series contains some updates to the b53 and bcm_sf2 drivers
> specifically for the 7278 Ethernet switch.
> 
> The first patch is technically a bug fix so it should ideally be
> backported to -stable, provided that Dan also agress with my resolution
> on this.
> 
> Patches #2 through #4 are minor changes to the core b53 driver to
> restore VLAN configuration upon system resumption as well as deny
> specific bridge/VLAN operations on port 7 with the 7278 which is special
> and does not support VLANs.
> 
> Patches #5 through #9 add support for matching VLAN TCI keys/masks to
> the CFP code.

Please ignore this version, some comments were not updated to match the
code, I will spin a v2 shortly.

Thank you

> 
> Florian Fainelli (9):
>   net: dsa: bcm_sf2: Fix overflow checks
>   net: dsa: b53: Restore VLAN entries upon (re)configuration
>   net: dsa: b53: Prevent tagged VLAN on port 7 for 7278
>   net: dsa: b53: Deny enslaving port 7 for 7278 into a bridge
>   net: dsa: bcm_sf2: Disable learning for ASP port
>   net: dsa: bcm_sf2: Check earlier for FLOW_EXT and FLOW_MAC_EXT
>   net: dsa: bcm_sf2: Move writing of CFP_DATA(5) into slicing functions
>   net: dsa: bcm_sf2: Add support for matching VLAN TCI
>   net: dsa: bcm_sf2: Support specifying VLAN tag egress rule
> 
>  drivers/net/dsa/b53/b53_common.c |  29 +++++++
>  drivers/net/dsa/bcm_sf2.c        |  10 ++-
>  drivers/net/dsa/bcm_sf2_cfp.c    | 139 ++++++++++++++++++++++---------
>  3 files changed, 136 insertions(+), 42 deletions(-)
> 

-- 
Florian

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

end of thread, other threads:[~2020-03-30 20:53 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-30 20:40 [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 Florian Fainelli
2020-03-30 20:40 ` [PATCH net-next 1/9] net: dsa: bcm_sf2: Fix overflow checks Florian Fainelli
2020-03-30 20:40 ` [PATCH net-next 2/9] net: dsa: b53: Restore VLAN entries upon (re)configuration Florian Fainelli
2020-03-30 20:40 ` [PATCH net-next 3/9] net: dsa: b53: Prevent tagged VLAN on port 7 for 7278 Florian Fainelli
2020-03-30 20:40 ` [PATCH net-next 4/9] net: dsa: b53: Deny enslaving port 7 for 7278 into a bridge Florian Fainelli
2020-03-30 20:40 ` [PATCH net-next 5/9] net: dsa: bcm_sf2: Disable learning for ASP port Florian Fainelli
2020-03-30 20:40 ` [PATCH net-next 6/9] net: dsa: bcm_sf2: Check earlier for FLOW_EXT and FLOW_MAC_EXT Florian Fainelli
2020-03-30 20:40 ` [PATCH net-next 7/9] net: dsa: bcm_sf2: Move writing of CFP_DATA(5) into slicing functions Florian Fainelli
2020-03-30 20:40 ` [PATCH net-next 8/9] net: dsa: bcm_sf2: Add support for matching VLAN TCI Florian Fainelli
2020-03-30 20:40 ` [PATCH net-next 9/9] net: dsa: bcm_sf2: Support specifying VLAN tag egress rule Florian Fainelli
2020-03-30 20:53 ` [PATCH net-next 0/9] net: dsa: b53 & bcm_sf2 updates for 7278 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).