mbox series

[net-next,v6,0/7] Hirschmann Hellcreek DSA driver

Message ID 20201004112911.25085-1-kurt@linutronix.de
Headers show
Series Hirschmann Hellcreek DSA driver | expand

Message

Kurt Kanzenbach Oct. 4, 2020, 11:29 a.m. UTC
Hi,

this series adds a DSA driver for the Hirschmann Hellcreek TSN switch
IP. Characteristics of that IP:

 * Full duplex Ethernet interface at 100/1000 Mbps on three ports
 * IEEE 802.1Q-compliant Ethernet Switch
 * IEEE 802.1Qbv Time-Aware scheduling support
 * IEEE 1588 and IEEE 802.1AS support

That IP is used e.g. in

 https://www.arrow.com/en/campaigns/arrow-kairos

Due to the hardware setup the switch driver is implemented using DSA. A special
tagging protocol is leveraged. Furthermore, this driver supports PTP and
hardware timestamping.

This version implements the DSA configure_vlan_while_not_filtering behavior by
caching any VLAN requests when vlan_filtering is not set and restoring it as
soon as it is. Due to the lack of a port forwarding matrix in hardware, VLANs
are used to reflect the initial DSA/switchdev port separation. Patch two is the
only one which changed and has to be re-reviewed. Thanks!

This work is part of the AccessTSN project: https://www.accesstsn.com/

The previous versions can be found here:

 * https://lkml.kernel.org/netdev/20200618064029.32168-1-kurt@linutronix.de/
 * https://lkml.kernel.org/netdev/20200710113611.3398-1-kurt@linutronix.de/
 * https://lkml.kernel.org/netdev/20200723081714.16005-1-kurt@linutronix.de/
 * https://lkml.kernel.org/netdev/20200820081118.10105-1-kurt@linutronix.de/
 * https://lkml.kernel.org/netdev/20200901125014.17801-1-kurt@linutronix.de/
 * https://lkml.kernel.org/netdev/20200904062739.3540-1-kurt@linutronix.de/

Changes since v5:

 * Implement configure_vlan_while_not_filtering behavior (Vladimir Oltean)
 * Minor cleanups

Changes since v4:

 * Fix W=1 compiler warnings (kernel test robot)
 * Add tags

Changes since v3:

 * Drop TAPRIO support (David Miller)
   => Switch to mutexes due to the lack of hrtimers
 * Use more specific compatible strings and add platform data (Andrew Lunn)
 * Fix Kconfig ordering (Andrew Lunn)

Changes since v2:

 * Make it compile by getting all requirements merged first (Jakub Kicinski, David Miller)
 * Use "tsn" for TSN register set (Rob Herring)
 * Fix DT binding issues (Rob Herring)

Changes since v1:

 * Code simplifications (Florian Fainelli, Vladimir Oltean)
 * Fix issues with hellcreek.yaml bindings (Florian Fainelli)
 * Clear reserved field in ptp v2 event messages (Richard Cochran)
 * Make use of generic ptp parsing function (Richard Cochran, Vladimir Oltean)
 * Fix Kconfig (Florian Fainelli)
 * Add tags (Florian Fainelli, Rob Herring, Richard Cochran) 

Changes since RFC ordered by reviewers:

 * Andrew Lunn
   * Use dev_dbg for debug messages
   * Get rid of __ function names where possible
   * Use reverse xmas tree variable ordering
   * Remove redundant/useless checks
   * Improve comments e.g. for PTP
   * Fix Kconfig ordering
   * Make LED handling more generic and provide info via DT
   * Setup advertisement of PHYs according to hardware
   * Drop debugfs patch
 * Jakub Kicinski
   * Fix compiler warnings
 * Florian Fainelli
   * Switch to YAML DT bindings
 * Richard Cochran
   * Fix typo
   * Add missing NULL checks

Kamil Alkhouri (2):
  net: dsa: hellcreek: Add PTP clock support
  net: dsa: hellcreek: Add support for hardware timestamping

Kurt Kanzenbach (5):
  net: dsa: Add tag handling for Hirschmann Hellcreek switches
  net: dsa: Add DSA driver for Hirschmann Hellcreek switches
  net: dsa: hellcreek: Add PTP status LEDs
  dt-bindings: Add vendor prefix for Hirschmann
  dt-bindings: net: dsa: Add documentation for Hellcreek switches

 .../bindings/net/dsa/hellcreek.yaml           |  127 ++
 .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
 drivers/net/dsa/Kconfig                       |    2 +
 drivers/net/dsa/Makefile                      |    1 +
 drivers/net/dsa/hirschmann/Kconfig            |    9 +
 drivers/net/dsa/hirschmann/Makefile           |    5 +
 drivers/net/dsa/hirschmann/hellcreek.c        | 1371 +++++++++++++++++
 drivers/net/dsa/hirschmann/hellcreek.h        |  292 ++++
 .../net/dsa/hirschmann/hellcreek_hwtstamp.c   |  479 ++++++
 .../net/dsa/hirschmann/hellcreek_hwtstamp.h   |   58 +
 drivers/net/dsa/hirschmann/hellcreek_ptp.c    |  452 ++++++
 drivers/net/dsa/hirschmann/hellcreek_ptp.h    |   76 +
 .../platform_data/hirschmann-hellcreek.h      |   23 +
 include/net/dsa.h                             |    2 +
 net/dsa/Kconfig                               |    6 +
 net/dsa/Makefile                              |    1 +
 net/dsa/tag_hellcreek.c                       |  101 ++
 17 files changed, 3007 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/hellcreek.yaml
 create mode 100644 drivers/net/dsa/hirschmann/Kconfig
 create mode 100644 drivers/net/dsa/hirschmann/Makefile
 create mode 100644 drivers/net/dsa/hirschmann/hellcreek.c
 create mode 100644 drivers/net/dsa/hirschmann/hellcreek.h
 create mode 100644 drivers/net/dsa/hirschmann/hellcreek_hwtstamp.c
 create mode 100644 drivers/net/dsa/hirschmann/hellcreek_hwtstamp.h
 create mode 100644 drivers/net/dsa/hirschmann/hellcreek_ptp.c
 create mode 100644 drivers/net/dsa/hirschmann/hellcreek_ptp.h
 create mode 100644 include/linux/platform_data/hirschmann-hellcreek.h
 create mode 100644 net/dsa/tag_hellcreek.c

Comments

Vladimir Oltean Oct. 4, 2020, 11:56 a.m. UTC | #1
On Sun, Oct 04, 2020 at 01:29:05PM +0200, 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>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  include/net/dsa.h       |   2 +
>  net/dsa/Kconfig         |   6 +++
>  net/dsa/Makefile        |   1 +
>  net/dsa/tag_hellcreek.c | 101 ++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 110 insertions(+)
>  create mode 100644 net/dsa/tag_hellcreek.c
> 
> diff --git a/include/net/dsa.h b/include/net/dsa.h
> index 8b0696e08cac..ee24476a1a4c 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..0895eda94bb5
> --- /dev/null
> +++ b/net/dsa/tag_hellcreek.c
> @@ -0,0 +1,101 @@
> +// 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);
> +	struct sk_buff *nskb;
> +	int padlen;
> +	u8 *tag;
> +
> +	padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len;
> +
> +	if (skb_tailroom(skb) >= padlen + HELLCREEK_TAG_LEN) {
> +		/* Let dsa_slave_xmit() free skb */
> +		if (__skb_put_padto(skb, skb->len + padlen, false))
> +			return NULL;
> +
> +		nskb = skb;
> +	} else {
> +		nskb = alloc_skb(NET_IP_ALIGN + skb->len +
> +				 padlen + HELLCREEK_TAG_LEN, GFP_ATOMIC);
> +		if (!nskb)
> +			return NULL;
> +		skb_reserve(nskb, NET_IP_ALIGN);
> +
> +		skb_reset_mac_header(nskb);
> +		skb_set_network_header(nskb,
> +				       skb_network_header(skb) - skb->head);
> +		skb_set_transport_header(nskb,
> +					 skb_transport_header(skb) - skb->head);
> +		skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len));
> +
> +		/* Let skb_put_padto() free nskb, and let dsa_slave_xmit() free
> +		 * skb
> +		 */
> +		if (skb_put_padto(nskb, nskb->len + padlen))
> +			return NULL;
> +
> +		consume_skb(skb);
> +	}
> +
> +	if (!nskb)
> +		return NULL;
> +
> +	/* Tag encoding */
> +	tag  = skb_put(nskb, HELLCREEK_TAG_LEN);
> +	*tag = BIT(dp->index);
> +
> +	return nskb;
> +}
> +
> +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,

After the changes in "Generic adjustment for flow dissector in DSA":
https://patchwork.ozlabs.org/project/netdev/list/?series=204347&state=*
you might want to set ".tail_tag = true" (see patch 07/15), either now
or later.

Either way,

Reviewed-by: Vladimir Oltean <olteanv@gmail.com>

> +};
> +
> +MODULE_LICENSE("Dual MIT/GPL");
> +MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_HELLCREEK);
> +
> +module_dsa_tag_driver(hellcreek_netdev_ops);
> -- 
> 2.20.1
>
Kurt Kanzenbach Oct. 5, 2020, 6:14 a.m. UTC | #2
On Sun Oct 04 2020, Vladimir Oltean wrote:
> On Sun, Oct 04, 2020 at 01:29:05PM +0200, Kurt Kanzenbach wrote:
>> +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,
>
> After the changes in "Generic adjustment for flow dissector in DSA":
> https://patchwork.ozlabs.org/project/netdev/list/?series=204347&state=*
> you might want to set ".tail_tag = true" (see patch 07/15), either now
> or later.
>
> Either way,
>
> Reviewed-by: Vladimir Oltean <olteanv@gmail.com>

Added it.

Thanks,
Kurt