--- /dev/null
+Switch (and switch-ish) device drivers HOWTO
+===========================
+
+Please note that the word "switch" is here used in very generic meaning.
+This include devices supporting L2/L3 but also various flow offloading chips,
+including switches embedded into SR-IOV NICs.
+
+Lets describe a topology a bit. Imagine the following example:
+
+       +----------------------------+    +---------------+
+       |     SOME switch chip       |    |      CPU      |
+       +----------------------------+    +---------------+
+       port1 port2 port3 port4 MNGMNT    |     PCI-E     |
+         |     |     |     |     |       +---------------+
+        PHY   PHY    |     |     |         |  NIC0 NIC1
+                     |     |     |         |   |    |
+                     |     |     +- PCI-E -+   |    |
+                     |     +------- MII -------+    |
+                     +------------- MII ------------+
+
+In this example, there are two independent lines between the switch silicon
+and CPU. NIC0 and NIC1 drivers are not aware of a switch presence. They are
+separate from the switch driver. SOME switch chip is by managed by a driver
+via PCI-E device MNGMNT. Note that MNGMNT device, NIC0 and NIC1 may be
+connected to some other type of bus.
+
+Now, for the previous example show the representation in kernel:
+
+       +----------------------------+    +---------------+
+       |     SOME switch chip       |    |      CPU      |
+       +----------------------------+    +---------------+
+       sw0p0 sw0p1 sw0p2 sw0p3 MNGMNT    |     PCI-E     |
+         |     |     |     |     |       +---------------+
+        PHY   PHY    |     |     |         |  eth0 eth1
+                     |     |     |         |   |    |
+                     |     |     +- PCI-E -+   |    |
+                     |     +------- MII -------+    |
+                     +------------- MII ------------+
+
+Lets call the example switch driver for SOME switch chip "SOMEswitch". This
+driver takes care of PCI-E device MNGMNT. There is a netdevice instance sw0pX
+created for each port of a switch. These netdevices are instances
+of "SOMEswitch" driver. sw0pX netdevices serve as a "representation"
+of the switch chip. eth0 and eth1 are instances of some other existing driver.
+
+The only difference of the switch-port netdevice from the ordinary netdevice
+is that is implements couple more NDOs:
+
+  ndo_switch_parent_id_get - This returns the same ID for two port netdevices
+                            of the same physical switch chip. This is
+                            mandatory to be implemented by all switch drivers
+                            and serves the caller for recognition of a port
+                            netdevice.
+  ndo_switch_parent_* - Functions that serve for a manipulation of the switch
+                       chip itself (it can be though of as a "parent" of the
+                       port, therefore the name). They are not port-specific.
+                       Caller might use arbitrary port netdevice of the same
+                       switch and it will make no difference.
+  ndo_switch_port_* - Functions that serve for a port-specific manipulation.
 
 F:     arch/*/kernel/pci-swiotlb.c
 F:     include/linux/swiotlb.h
 
+SWITCHDEV
+M:     Jiri Pirko <jiri@resnulli.us>
+L:     netdev@vger.kernel.org
+S:     Supported
+F:     net/switchdev/
+F:     include/net/switchdev.h
+
 SYNOPSYS ARC ARCHITECTURE
 M:     Vineet Gupta <vgupta@synopsys.com>
 S:     Supported
 
  *     performing GSO on a packet. The device returns true if it is
  *     able to GSO the packet, false otherwise. If the return value is
  *     false the stack will do software GSO.
+ *
+ * int (*ndo_switch_parent_id_get)(struct net_device *dev,
+ *                                struct netdev_phys_item_id *psid);
+ *     Called to get an ID of the switch chip this port is part of.
+ *     If driver implements this, it indicates that it represents a port
+ *     of a switch chip.
  */
 struct net_device_ops {
        int                     (*ndo_init)(struct net_device *dev);
        int                     (*ndo_get_lock_subclass)(struct net_device *dev);
        bool                    (*ndo_gso_check) (struct sk_buff *skb,
                                                  struct net_device *dev);
+#ifdef CONFIG_NET_SWITCHDEV
+       int                     (*ndo_switch_parent_id_get)(struct net_device *dev,
+                                                           struct netdev_phys_item_id *psid);
+#endif
 };
 
 /**
 
--- /dev/null
+/*
+ * include/net/switchdev.h - Switch device API
+ * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef _LINUX_SWITCHDEV_H_
+#define _LINUX_SWITCHDEV_H_
+
+#include <linux/netdevice.h>
+
+#ifdef CONFIG_NET_SWITCHDEV
+
+int netdev_switch_parent_id_get(struct net_device *dev,
+                               struct netdev_phys_item_id *psid);
+
+#else
+
+static inline int netdev_switch_parent_id_get(struct net_device *dev,
+                                             struct netdev_phys_item_id *psid)
+{
+       return -EOPNOTSUPP;
+}
+
+#endif
+
+#endif /* _LINUX_SWITCHDEV_H_ */
 
 source "net/netlink/Kconfig"
 source "net/mpls/Kconfig"
 source "net/hsr/Kconfig"
+source "net/switchdev/Kconfig"
 
 config RPS
        boolean
 
 obj-$(CONFIG_VSOCKETS) += vmw_vsock/
 obj-$(CONFIG_NET_MPLS_GSO)     += mpls/
 obj-$(CONFIG_HSR)              += hsr/
+ifneq ($(CONFIG_NET_SWITCHDEV),)
+obj-y                          += switchdev/
+endif
 
--- /dev/null
+#
+# Configuration for Switch device support
+#
+
+config NET_SWITCHDEV
+       boolean "Switch (and switch-ish) device support (EXPERIMENTAL)"
+       depends on INET
+       ---help---
+         This module provides glue between core networking code and device
+         drivers in order to support hardware switch chips in very generic
+         meaning of the word "switch". This include devices supporting L2/L3 but
+         also various flow offloading chips, including switches embedded into
+         SR-IOV NICs.
 
--- /dev/null
+#
+# Makefile for the Switch device API
+#
+
+obj-$(CONFIG_NET_SWITCHDEV) += switchdev.o
 
--- /dev/null
+/*
+ * net/switchdev/switchdev.c - Switch device API
+ * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <net/switchdev.h>
+
+/**
+ *     netdev_switch_parent_id_get - Get ID of a switch
+ *     @dev: port device
+ *     @psid: switch ID
+ *
+ *     Get ID of a switch this port is part of.
+ */
+int netdev_switch_parent_id_get(struct net_device *dev,
+                               struct netdev_phys_item_id *psid)
+{
+       const struct net_device_ops *ops = dev->netdev_ops;
+
+       if (!ops->ndo_switch_parent_id_get)
+               return -EOPNOTSUPP;
+       return ops->ndo_switch_parent_id_get(dev, psid);
+}
+EXPORT_SYMBOL(netdev_switch_parent_id_get);