dsa: add support for Arrow XRS700x tag trailer
authorGeorge McCollister <george.mccollister@gmail.com>
Thu, 14 Jan 2021 19:57:32 +0000 (13:57 -0600)
committerJakub Kicinski <kuba@kernel.org>
Fri, 15 Jan 2021 23:36:31 +0000 (15:36 -0800)
Add support for Arrow SpeedChips XRS700x single byte tag trailer. This
is modeled on tag_trailer.c which works in a similar way.

Signed-off-by: George McCollister <george.mccollister@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/dsa.h
net/dsa/Kconfig
net/dsa/Makefile
net/dsa/tag_xrs700x.c [new file with mode: 0644]

index 06e3784..fa537af 100644 (file)
@@ -46,6 +46,7 @@ struct phylink_link_state;
 #define DSA_TAG_PROTO_AR9331_VALUE             16
 #define DSA_TAG_PROTO_RTL4_A_VALUE             17
 #define DSA_TAG_PROTO_HELLCREEK_VALUE          18
+#define DSA_TAG_PROTO_XRS700X_VALUE            19
 
 enum dsa_tag_protocol {
        DSA_TAG_PROTO_NONE              = DSA_TAG_PROTO_NONE_VALUE,
@@ -67,6 +68,7 @@ enum dsa_tag_protocol {
        DSA_TAG_PROTO_AR9331            = DSA_TAG_PROTO_AR9331_VALUE,
        DSA_TAG_PROTO_RTL4_A            = DSA_TAG_PROTO_RTL4_A_VALUE,
        DSA_TAG_PROTO_HELLCREEK         = DSA_TAG_PROTO_HELLCREEK_VALUE,
+       DSA_TAG_PROTO_XRS700X           = DSA_TAG_PROTO_XRS700X_VALUE,
 };
 
 struct packet_type;
index dfecd7b..2d226a5 100644 (file)
@@ -139,4 +139,10 @@ config NET_DSA_TAG_TRAILER
          Say Y or M if you want to enable support for tagging frames at
          with a trailed. e.g. Marvell 88E6060.
 
+config NET_DSA_TAG_XRS700X
+       tristate "Tag driver for XRS700x switches"
+       help
+         Say Y or M if you want to enable support for tagging frames for
+         Arrow SpeedChips XRS700x switches that use a single byte tag trailer.
+
 endif
index 0fb2b75..92cea21 100644 (file)
@@ -18,3 +18,4 @@ obj-$(CONFIG_NET_DSA_TAG_OCELOT) += tag_ocelot.o
 obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o
 obj-$(CONFIG_NET_DSA_TAG_SJA1105) += tag_sja1105.o
 obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
+obj-$(CONFIG_NET_DSA_TAG_XRS700X) += tag_xrs700x.o
diff --git a/net/dsa/tag_xrs700x.c b/net/dsa/tag_xrs700x.c
new file mode 100644 (file)
index 0000000..db0ed1a
--- /dev/null
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * XRS700x tag format handling
+ * Copyright (c) 2008-2009 Marvell Semiconductor
+ * Copyright (c) 2020 NovaTech LLC
+ */
+
+#include <linux/bitops.h>
+
+#include "dsa_priv.h"
+
+static struct sk_buff *xrs700x_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct dsa_port *dp = dsa_slave_to_port(dev);
+       u8 *trailer;
+
+       trailer = skb_put(skb, 1);
+       trailer[0] = BIT(dp->index);
+
+       return skb;
+}
+
+static struct sk_buff *xrs700x_rcv(struct sk_buff *skb, struct net_device *dev,
+                                  struct packet_type *pt)
+{
+       int source_port;
+       u8 *trailer;
+
+       trailer = skb_tail_pointer(skb) - 1;
+
+       source_port = ffs((int)trailer[0]) - 1;
+
+       if (source_port < 0)
+               return NULL;
+
+       skb->dev = dsa_master_find_slave(dev, 0, source_port);
+       if (!skb->dev)
+               return NULL;
+
+       if (pskb_trim_rcsum(skb, skb->len - 1))
+               return NULL;
+
+       /* Frame is forwarded by hardware, don't forward in software. */
+       skb->offload_fwd_mark = 1;
+
+       return skb;
+}
+
+static const struct dsa_device_ops xrs700x_netdev_ops = {
+       .name   = "xrs700x",
+       .proto  = DSA_TAG_PROTO_XRS700X,
+       .xmit   = xrs700x_xmit,
+       .rcv    = xrs700x_rcv,
+       .overhead = 1,
+       .tail_tag = true,
+};
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_XRS700X);
+
+module_dsa_tag_driver(xrs700x_netdev_ops);