--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -81,6 +81,7 @@
 #define ETH_P_1588	0x88F7		/* IEEE 1588 Timesync */
 #define ETH_P_FCOE	0x8906		/* Fibre Channel over Ethernet  */
 #define ETH_P_FIP	0x8914		/* FCoE Initialization Protocol */
+#define ETH_P_QINQ	0x9100		/* QinQ VLAN Stacking Protocol */
 #define ETH_P_EDSA	0xDADA		/* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
 
 /*
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -174,6 +174,9 @@ netdev_tx_t dsa_xmit(struct sk_buff *skb
 /* tag_edsa.c */
 netdev_tx_t edsa_xmit(struct sk_buff *skb, struct net_device *dev);
 
+/* tag_qinq.c */
+netdev_tx_t qinq_xmit(struct sk_buff *skb, struct net_device *dev);
+
 /* tag_trailer.c */
 netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev);
 
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -23,6 +23,10 @@ config NET_DSA_TAG_TRAILER
 	bool
 	default n
 
+config NET_DSA_TAG_QINQ
+	bool
+	default y
+
 
 # switch drivers
 config NET_DSA_MV88E6XXX
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -1,6 +1,7 @@
 # tagging formats
 obj-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o
 obj-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o
+obj-$(CONFIG_NET_DSA_TAG_QINQ) += tag_qinq.o
 obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
 
 # switch drivers
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -321,6 +321,19 @@ static const struct net_device_ops edsa_
 	.ndo_do_ioctl		= dsa_slave_ioctl,
 };
 #endif
+#ifdef CONFIG_NET_DSA_TAG_QINQ
+static const struct net_device_ops qinq_netdev_ops = {
+	.ndo_init		= dsa_slave_init,
+	.ndo_open	 	= dsa_slave_open,
+	.ndo_stop		= dsa_slave_close,
+	.ndo_start_xmit		= qinq_xmit,
+	.ndo_change_rx_flags	= dsa_slave_change_rx_flags,
+	.ndo_set_rx_mode	= dsa_slave_set_rx_mode,
+	.ndo_set_multicast_list = dsa_slave_set_rx_mode,
+	.ndo_set_mac_address	= dsa_slave_set_mac_address,
+	.ndo_do_ioctl		= dsa_slave_ioctl,
+};
+#endif
 #ifdef CONFIG_NET_DSA_TAG_TRAILER
 static const struct net_device_ops trailer_netdev_ops = {
 	.ndo_init		= dsa_slave_init,
@@ -366,6 +379,11 @@ dsa_slave_create(struct dsa_switch *ds, 
 		slave_dev->netdev_ops = &edsa_netdev_ops;
 		break;
 #endif
+#ifdef CONFIG_NET_DSA_TAG_QINQ
+	case htons(ETH_P_QINQ):
+		slave_dev->netdev_ops = &qinq_netdev_ops;
+		break;
+#endif
 #ifdef CONFIG_NET_DSA_TAG_TRAILER
 	case htons(ETH_P_TRAILER):
 		slave_dev->netdev_ops = &trailer_netdev_ops;
