f2f42a54e8
The qca8k patch series brings the numbering to 799. This patch renames 7xx patches to create space for more backports to be added. Signed-off-by: Matthew Hagan <mnhagan88@gmail.com> [rename 729->719] Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
181 lines
5.5 KiB
Diff
181 lines
5.5 KiB
Diff
From 964dbf186eaa84d409c359ddf09c827a3fbe8228 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
|
|
Date: Wed, 17 Mar 2021 11:29:26 +0100
|
|
Subject: [PATCH] net: dsa: tag_brcm: add support for legacy tags
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Add support for legacy Broadcom tags, which are similar to DSA_TAG_PROTO_BRCM.
|
|
These tags are used on BCM5325, BCM5365 and BCM63xx switches.
|
|
|
|
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
include/net/dsa.h | 2 +
|
|
net/dsa/Kconfig | 7 +++
|
|
net/dsa/tag_brcm.c | 107 +++++++++++++++++++++++++++++++++++++++++++--
|
|
3 files changed, 113 insertions(+), 3 deletions(-)
|
|
|
|
--- a/include/net/dsa.h
|
|
+++ b/include/net/dsa.h
|
|
@@ -45,10 +45,12 @@ struct phylink_link_state;
|
|
#define DSA_TAG_PROTO_OCELOT_VALUE 15
|
|
#define DSA_TAG_PROTO_AR9331_VALUE 16
|
|
#define DSA_TAG_PROTO_RTL4_A_VALUE 17
|
|
+#define DSA_TAG_PROTO_BRCM_LEGACY_VALUE 22
|
|
|
|
enum dsa_tag_protocol {
|
|
DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
|
|
DSA_TAG_PROTO_BRCM = DSA_TAG_PROTO_BRCM_VALUE,
|
|
+ DSA_TAG_PROTO_BRCM_LEGACY = DSA_TAG_PROTO_BRCM_LEGACY_VALUE,
|
|
DSA_TAG_PROTO_BRCM_PREPEND = DSA_TAG_PROTO_BRCM_PREPEND_VALUE,
|
|
DSA_TAG_PROTO_DSA = DSA_TAG_PROTO_DSA_VALUE,
|
|
DSA_TAG_PROTO_EDSA = DSA_TAG_PROTO_EDSA_VALUE,
|
|
--- a/net/dsa/Kconfig
|
|
+++ b/net/dsa/Kconfig
|
|
@@ -47,6 +47,13 @@ config NET_DSA_TAG_BRCM
|
|
Say Y if you want to enable support for tagging frames for the
|
|
Broadcom switches which place the tag after the MAC source address.
|
|
|
|
+config NET_DSA_TAG_BRCM_LEGACY
|
|
+ tristate "Tag driver for Broadcom legacy switches using in-frame headers"
|
|
+ select NET_DSA_TAG_BRCM_COMMON
|
|
+ help
|
|
+ Say Y if you want to enable support for tagging frames for the
|
|
+ Broadcom legacy switches which place the tag after the MAC source
|
|
+ address.
|
|
|
|
config NET_DSA_TAG_BRCM_PREPEND
|
|
tristate "Tag driver for Broadcom switches using prepended headers"
|
|
--- a/net/dsa/tag_brcm.c
|
|
+++ b/net/dsa/tag_brcm.c
|
|
@@ -11,9 +11,26 @@
|
|
|
|
#include "dsa_priv.h"
|
|
|
|
-/* This tag length is 4 bytes, older ones were 6 bytes, we do not
|
|
- * handle them
|
|
- */
|
|
+/* Legacy Broadcom tag (6 bytes) */
|
|
+#define BRCM_LEG_TAG_LEN 6
|
|
+
|
|
+/* Type fields */
|
|
+/* 1st byte in the tag */
|
|
+#define BRCM_LEG_TYPE_HI 0x88
|
|
+/* 2nd byte in the tag */
|
|
+#define BRCM_LEG_TYPE_LO 0x74
|
|
+
|
|
+/* Tag fields */
|
|
+/* 3rd byte in the tag */
|
|
+#define BRCM_LEG_UNICAST (0 << 5)
|
|
+#define BRCM_LEG_MULTICAST (1 << 5)
|
|
+#define BRCM_LEG_EGRESS (2 << 5)
|
|
+#define BRCM_LEG_INGRESS (3 << 5)
|
|
+
|
|
+/* 6th byte in the tag */
|
|
+#define BRCM_LEG_PORT_ID (0xf)
|
|
+
|
|
+/* Newer Broadcom tag (4 bytes) */
|
|
#define BRCM_TAG_LEN 4
|
|
|
|
/* Tag is constructed and desconstructed using byte by byte access
|
|
@@ -194,6 +211,87 @@ DSA_TAG_DRIVER(brcm_netdev_ops);
|
|
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM);
|
|
#endif
|
|
|
|
+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
|
|
+static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
|
|
+ struct net_device *dev)
|
|
+{
|
|
+ struct dsa_port *dp = dsa_slave_to_port(dev);
|
|
+ u8 *brcm_tag;
|
|
+
|
|
+ /* The Ethernet switch we are interfaced with needs packets to be at
|
|
+ * least 64 bytes (including FCS) otherwise they will be discarded when
|
|
+ * they enter the switch port logic. When Broadcom tags are enabled, we
|
|
+ * need to make sure that packets are at least 70 bytes
|
|
+ * (including FCS and tag) because the length verification is done after
|
|
+ * the Broadcom tag is stripped off the ingress packet.
|
|
+ *
|
|
+ * Let dsa_slave_xmit() free the SKB
|
|
+ */
|
|
+ if (__skb_put_padto(skb, ETH_ZLEN + BRCM_LEG_TAG_LEN, false))
|
|
+ return NULL;
|
|
+
|
|
+ skb_push(skb, BRCM_LEG_TAG_LEN);
|
|
+
|
|
+ memmove(skb->data, skb->data + BRCM_LEG_TAG_LEN, 2 * ETH_ALEN);
|
|
+
|
|
+ brcm_tag = skb->data + 2 * ETH_ALEN;
|
|
+
|
|
+ /* Broadcom tag type */
|
|
+ brcm_tag[0] = BRCM_LEG_TYPE_HI;
|
|
+ brcm_tag[1] = BRCM_LEG_TYPE_LO;
|
|
+
|
|
+ /* Broadcom tag value */
|
|
+ brcm_tag[2] = BRCM_LEG_EGRESS;
|
|
+ brcm_tag[3] = 0;
|
|
+ brcm_tag[4] = 0;
|
|
+ brcm_tag[5] = dp->index & BRCM_LEG_PORT_ID;
|
|
+
|
|
+ return skb;
|
|
+}
|
|
+
|
|
+static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
|
|
+ struct net_device *dev,
|
|
+ struct packet_type *pt)
|
|
+{
|
|
+ int source_port;
|
|
+ u8 *brcm_tag;
|
|
+
|
|
+ if (unlikely(!pskb_may_pull(skb, BRCM_LEG_PORT_ID)))
|
|
+ return NULL;
|
|
+
|
|
+ brcm_tag = skb->data - 2;
|
|
+
|
|
+ source_port = brcm_tag[5] & BRCM_LEG_PORT_ID;
|
|
+
|
|
+ skb->dev = dsa_master_find_slave(dev, 0, source_port);
|
|
+ if (!skb->dev)
|
|
+ return NULL;
|
|
+
|
|
+ /* Remove Broadcom tag and update checksum */
|
|
+ skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
|
|
+
|
|
+ skb->offload_fwd_mark = 1;
|
|
+
|
|
+ /* Move the Ethernet DA and SA */
|
|
+ memmove(skb->data - ETH_HLEN,
|
|
+ skb->data - ETH_HLEN - BRCM_LEG_TAG_LEN,
|
|
+ 2 * ETH_ALEN);
|
|
+
|
|
+ return skb;
|
|
+}
|
|
+
|
|
+static const struct dsa_device_ops brcm_legacy_netdev_ops = {
|
|
+ .name = "brcm-legacy",
|
|
+ .proto = DSA_TAG_PROTO_BRCM_LEGACY,
|
|
+ .xmit = brcm_leg_tag_xmit,
|
|
+ .rcv = brcm_leg_tag_rcv,
|
|
+ .overhead = BRCM_LEG_TAG_LEN,
|
|
+};
|
|
+
|
|
+DSA_TAG_DRIVER(brcm_legacy_netdev_ops);
|
|
+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY);
|
|
+#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY */
|
|
+
|
|
#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
|
|
static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb,
|
|
struct net_device *dev)
|
|
@@ -226,6 +324,9 @@ static struct dsa_tag_driver *dsa_tag_dr
|
|
#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM)
|
|
&DSA_TAG_DRIVER_NAME(brcm_netdev_ops),
|
|
#endif
|
|
+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
|
|
+ &DSA_TAG_DRIVER_NAME(brcm_legacy_netdev_ops),
|
|
+#endif
|
|
#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
|
|
&DSA_TAG_DRIVER_NAME(brcm_prepend_netdev_ops),
|
|
#endif
|