Message ID | 20201103071101.3222-2-kurt@linutronix.de |
---|---|
State | New |
Headers | show |
Series | [net-next,v8,1/8] net: dsa: Add tag handling for Hirschmann Hellcreek switches | expand |
On Tue, Nov 03, 2020 at 08:10:54AM +0100, Kurt Kanzenbach wrote: > The Hirschmann Hellcreek TSN switches have a special tagging protocol for frames > exchanged between the CPU port and the master interface. The format is a one > byte trailer indicating the destination or origin port. > > It's quite similar to the Micrel KSZ tagging. That's why the implementation is > based on that code. > > Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> > --- > diff --git a/net/dsa/tag_hellcreek.c b/net/dsa/tag_hellcreek.c > new file mode 100644 > index 000000000000..2061de06eafb > --- /dev/null > +++ b/net/dsa/tag_hellcreek.c > @@ -0,0 +1,66 @@ > +// SPDX-License-Identifier: (GPL-2.0 OR MIT) > +/* > + * net/dsa/tag_hellcreek.c - Hirschmann Hellcreek switch tag format handling > + * > + * Copyright (C) 2019,2020 Linutronix GmbH > + * Author Kurt Kanzenbach <kurt@linutronix.de> > + * > + * Based on tag_ksz.c. > + */ > + > +#include <linux/etherdevice.h> > +#include <linux/list.h> > +#include <linux/slab.h> You probably don't need these includes any longer, but you don't have to resend this series just to remove them, you could do that afterwards. > +#include <net/dsa.h> > + > +#include "dsa_priv.h" > + > +#define HELLCREEK_TAG_LEN 1 > + > +static struct sk_buff *hellcreek_xmit(struct sk_buff *skb, > + struct net_device *dev) > +{ > + struct dsa_port *dp = dsa_slave_to_port(dev); > + u8 *tag; > + > + /* Tag encoding */ > + tag = skb_put(skb, HELLCREEK_TAG_LEN); > + *tag = BIT(dp->index); > + > + return skb; > +} > + > +static struct sk_buff *hellcreek_rcv(struct sk_buff *skb, > + struct net_device *dev, > + struct packet_type *pt) > +{ > + /* Tag decoding */ > + u8 *tag = skb_tail_pointer(skb) - HELLCREEK_TAG_LEN; > + unsigned int port = tag[0] & 0x03; > + > + skb->dev = dsa_master_find_slave(dev, 0, port); > + if (!skb->dev) { > + netdev_warn(dev, "Failed to get source port: %d\n", port); > + return NULL; > + } > + > + pskb_trim_rcsum(skb, skb->len - HELLCREEK_TAG_LEN); > + > + skb->offload_fwd_mark = true; > + > + return skb; > +} > + > +static const struct dsa_device_ops hellcreek_netdev_ops = { > + .name = "hellcreek", > + .proto = DSA_TAG_PROTO_HELLCREEK, > + .xmit = hellcreek_xmit, > + .rcv = hellcreek_rcv, > + .overhead = HELLCREEK_TAG_LEN, > + .tail_tag = true, > +}; > + > +MODULE_LICENSE("Dual MIT/GPL"); > +MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_HELLCREEK); > + > +module_dsa_tag_driver(hellcreek_netdev_ops); > -- > 2.20.1 > Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
diff --git a/include/net/dsa.h b/include/net/dsa.h index 35429a140dfa..04e93bafb7bd 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -45,6 +45,7 @@ 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_HELLCREEK_VALUE 18 enum dsa_tag_protocol { DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, @@ -65,6 +66,7 @@ enum dsa_tag_protocol { DSA_TAG_PROTO_OCELOT = DSA_TAG_PROTO_OCELOT_VALUE, 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, }; struct packet_type; diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig index 1f9b9b11008c..d975614f7dd6 100644 --- a/net/dsa/Kconfig +++ b/net/dsa/Kconfig @@ -56,6 +56,12 @@ config NET_DSA_TAG_BRCM_PREPEND Broadcom switches which places the tag before the Ethernet header (prepended). +config NET_DSA_TAG_HELLCREEK + tristate "Tag driver for Hirschmann Hellcreek TSN switches" + help + Say Y or M if you want to enable support for tagging frames + for the Hirschmann Hellcreek TSN switches. + config NET_DSA_TAG_GSWIP tristate "Tag driver for Lantiq / Intel GSWIP switches" help diff --git a/net/dsa/Makefile b/net/dsa/Makefile index 4f47b2025ff5..e25d5457964a 100644 --- a/net/dsa/Makefile +++ b/net/dsa/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_NET_DSA_TAG_BRCM_COMMON) += tag_brcm.o obj-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o obj-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o +obj-$(CONFIG_NET_DSA_TAG_HELLCREEK) += tag_hellcreek.o obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o diff --git a/net/dsa/tag_hellcreek.c b/net/dsa/tag_hellcreek.c new file mode 100644 index 000000000000..2061de06eafb --- /dev/null +++ b/net/dsa/tag_hellcreek.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * net/dsa/tag_hellcreek.c - Hirschmann Hellcreek switch tag format handling + * + * Copyright (C) 2019,2020 Linutronix GmbH + * Author Kurt Kanzenbach <kurt@linutronix.de> + * + * Based on tag_ksz.c. + */ + +#include <linux/etherdevice.h> +#include <linux/list.h> +#include <linux/slab.h> +#include <net/dsa.h> + +#include "dsa_priv.h" + +#define HELLCREEK_TAG_LEN 1 + +static struct sk_buff *hellcreek_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct dsa_port *dp = dsa_slave_to_port(dev); + u8 *tag; + + /* Tag encoding */ + tag = skb_put(skb, HELLCREEK_TAG_LEN); + *tag = BIT(dp->index); + + return skb; +} + +static struct sk_buff *hellcreek_rcv(struct sk_buff *skb, + struct net_device *dev, + struct packet_type *pt) +{ + /* Tag decoding */ + u8 *tag = skb_tail_pointer(skb) - HELLCREEK_TAG_LEN; + unsigned int port = tag[0] & 0x03; + + skb->dev = dsa_master_find_slave(dev, 0, port); + if (!skb->dev) { + netdev_warn(dev, "Failed to get source port: %d\n", port); + return NULL; + } + + pskb_trim_rcsum(skb, skb->len - HELLCREEK_TAG_LEN); + + skb->offload_fwd_mark = true; + + return skb; +} + +static const struct dsa_device_ops hellcreek_netdev_ops = { + .name = "hellcreek", + .proto = DSA_TAG_PROTO_HELLCREEK, + .xmit = hellcreek_xmit, + .rcv = hellcreek_rcv, + .overhead = HELLCREEK_TAG_LEN, + .tail_tag = true, +}; + +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_HELLCREEK); + +module_dsa_tag_driver(hellcreek_netdev_ops);
The Hirschmann Hellcreek TSN switches have a special tagging protocol for frames exchanged between the CPU port and the master interface. The format is a one byte trailer indicating the destination or origin port. It's quite similar to the Micrel KSZ tagging. That's why the implementation is based on that code. Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> --- include/net/dsa.h | 2 ++ net/dsa/Kconfig | 6 ++++ net/dsa/Makefile | 1 + net/dsa/tag_hellcreek.c | 66 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 net/dsa/tag_hellcreek.c