kernel: backport b53/bcm_sf2 changes from v5.7
[openwrt/staging/pepe2k.git] / target / linux / generic / backport-5.4 / 707-v5.7-0012-net-dsa-bcm_sf2-Support-specifying-VLAN-tag-egress-r.patch
1 From 8b3abe304c5f1057b7bac70fd5576dfa67e3e2b3 Mon Sep 17 00:00:00 2001
2 From: Florian Fainelli <f.fainelli@gmail.com>
3 Date: Mon, 30 Mar 2020 14:38:54 -0700
4 Subject: [PATCH] net: dsa: bcm_sf2: Support specifying VLAN tag egress rule
5
6 The port to which the ASP is connected on 7278 is not capable of
7 processing VLAN tags as part of the Ethernet frame, so allow an user to
8 configure the egress VLAN policy they want to see applied by purposing
9 the h_ext.data[1] field. Bit 0 is used to indicate that 0=tagged,
10 1=untagged.
11
12 Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
13 Signed-off-by: David S. Miller <davem@davemloft.net>
14 ---
15 drivers/net/dsa/bcm_sf2_cfp.c | 40 +++++++++++++++++++++++++++++++++--
16 1 file changed, 38 insertions(+), 2 deletions(-)
17
18 --- a/drivers/net/dsa/bcm_sf2_cfp.c
19 +++ b/drivers/net/dsa/bcm_sf2_cfp.c
20 @@ -13,6 +13,8 @@
21 #include <net/dsa.h>
22 #include <linux/bitmap.h>
23 #include <net/flow_offload.h>
24 +#include <net/switchdev.h>
25 +#include <uapi/linux/if_bridge.h>
26
27 #include "bcm_sf2.h"
28 #include "bcm_sf2_regs.h"
29 @@ -847,7 +849,9 @@ static int bcm_sf2_cfp_rule_insert(struc
30 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
31 s8 cpu_port = ds->ports[port].cpu_dp->index;
32 __u64 ring_cookie = fs->ring_cookie;
33 + struct switchdev_obj_port_vlan vlan;
34 unsigned int queue_num, port_num;
35 + u16 vid;
36 int ret;
37
38 /* This rule is a Wake-on-LAN filter and we must specifically
39 @@ -867,6 +871,34 @@ static int bcm_sf2_cfp_rule_insert(struc
40 dsa_is_cpu_port(ds, port_num)) ||
41 port_num >= priv->hw_params.num_ports)
42 return -EINVAL;
43 +
44 + /* If the rule is matching a particular VLAN, make sure that we honor
45 + * the matching and have it tagged or untagged on the destination port,
46 + * we do this on egress with a VLAN entry. The egress tagging attribute
47 + * is expected to be provided in h_ext.data[1] bit 0. A 1 means untagged,
48 + * a 0 means tagged.
49 + */
50 + if (fs->flow_type & FLOW_EXT) {
51 + /* We cannot support matching multiple VLAN IDs yet */
52 + if ((be16_to_cpu(fs->m_ext.vlan_tci) & VLAN_VID_MASK) !=
53 + VLAN_VID_MASK)
54 + return -EINVAL;
55 +
56 + vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK;
57 + vlan.vid_begin = vid;
58 + vlan.vid_end = vid;
59 + if (cpu_to_be32(fs->h_ext.data[1]) & 1)
60 + vlan.flags = BRIDGE_VLAN_INFO_UNTAGGED;
61 + else
62 + vlan.flags = 0;
63 +
64 + ret = ds->ops->port_vlan_prepare(ds, port_num, &vlan);
65 + if (ret)
66 + return ret;
67 +
68 + ds->ops->port_vlan_add(ds, port_num, &vlan);
69 + }
70 +
71 /*
72 * We have a small oddity where Port 6 just does not have a
73 * valid bit here (so we substract by one).
74 @@ -902,14 +934,18 @@ static int bcm_sf2_cfp_rule_set(struct d
75 int ret = -EINVAL;
76
77 /* Check for unsupported extensions */
78 - if ((fs->flow_type & FLOW_MAC_EXT) ||
79 - fs->m_ext.data[1])
80 + if (fs->flow_type & FLOW_MAC_EXT)
81 return -EINVAL;
82
83 if (fs->location != RX_CLS_LOC_ANY &&
84 fs->location > bcm_sf2_cfp_rule_size(priv))
85 return -EINVAL;
86
87 + if ((fs->flow_type & FLOW_EXT) &&
88 + !(ds->ops->port_vlan_prepare || ds->ops->port_vlan_add ||
89 + ds->ops->port_vlan_del))
90 + return -EOPNOTSUPP;
91 +
92 if (fs->location != RX_CLS_LOC_ANY &&
93 test_bit(fs->location, priv->cfp.used))
94 return -EBUSY;