| 1 | --- a/include/linux/if_ether.h |
| 2 | +++ b/include/linux/if_ether.h |
| 3 | @@ -81,6 +81,7 @@ |
| 4 | #define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */ |
| 5 | #define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */ |
| 6 | #define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */ |
| 7 | +#define ETH_P_QINQ 0x9100 /* QinQ VLAN Stacking Protocol */ |
| 8 | #define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */ |
| 9 | |
| 10 | /* |
| 11 | --- a/net/dsa/dsa_priv.h |
| 12 | +++ b/net/dsa/dsa_priv.h |
| 13 | @@ -174,6 +174,9 @@ netdev_tx_t dsa_xmit(struct sk_buff *skb |
| 14 | /* tag_edsa.c */ |
| 15 | netdev_tx_t edsa_xmit(struct sk_buff *skb, struct net_device *dev); |
| 16 | |
| 17 | +/* tag_qinq.c */ |
| 18 | +netdev_tx_t qinq_xmit(struct sk_buff *skb, struct net_device *dev); |
| 19 | + |
| 20 | /* tag_trailer.c */ |
| 21 | netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev); |
| 22 | |
| 23 | --- a/net/dsa/Kconfig |
| 24 | +++ b/net/dsa/Kconfig |
| 25 | @@ -23,6 +23,10 @@ config NET_DSA_TAG_TRAILER |
| 26 | bool |
| 27 | default n |
| 28 | |
| 29 | +config NET_DSA_TAG_QINQ |
| 30 | + bool |
| 31 | + default y |
| 32 | + |
| 33 | |
| 34 | # switch drivers |
| 35 | config NET_DSA_MV88E6XXX |
| 36 | --- a/net/dsa/Makefile |
| 37 | +++ b/net/dsa/Makefile |
| 38 | @@ -1,6 +1,7 @@ |
| 39 | # tagging formats |
| 40 | obj-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o |
| 41 | obj-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o |
| 42 | +obj-$(CONFIG_NET_DSA_TAG_QINQ) += tag_qinq.o |
| 43 | obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o |
| 44 | |
| 45 | # switch drivers |
| 46 | --- a/net/dsa/slave.c |
| 47 | +++ b/net/dsa/slave.c |
| 48 | @@ -321,6 +321,19 @@ static const struct net_device_ops edsa_ |
| 49 | .ndo_do_ioctl = dsa_slave_ioctl, |
| 50 | }; |
| 51 | #endif |
| 52 | +#ifdef CONFIG_NET_DSA_TAG_QINQ |
| 53 | +static const struct net_device_ops qinq_netdev_ops = { |
| 54 | + .ndo_init = dsa_slave_init, |
| 55 | + .ndo_open = dsa_slave_open, |
| 56 | + .ndo_stop = dsa_slave_close, |
| 57 | + .ndo_start_xmit = qinq_xmit, |
| 58 | + .ndo_change_rx_flags = dsa_slave_change_rx_flags, |
| 59 | + .ndo_set_rx_mode = dsa_slave_set_rx_mode, |
| 60 | + .ndo_set_multicast_list = dsa_slave_set_rx_mode, |
| 61 | + .ndo_set_mac_address = dsa_slave_set_mac_address, |
| 62 | + .ndo_do_ioctl = dsa_slave_ioctl, |
| 63 | +}; |
| 64 | +#endif |
| 65 | #ifdef CONFIG_NET_DSA_TAG_TRAILER |
| 66 | static const struct net_device_ops trailer_netdev_ops = { |
| 67 | .ndo_init = dsa_slave_init, |
| 68 | @@ -366,6 +379,11 @@ dsa_slave_create(struct dsa_switch *ds, |
| 69 | slave_dev->netdev_ops = &edsa_netdev_ops; |
| 70 | break; |
| 71 | #endif |
| 72 | +#ifdef CONFIG_NET_DSA_TAG_QINQ |
| 73 | + case htons(ETH_P_QINQ): |
| 74 | + slave_dev->netdev_ops = &qinq_netdev_ops; |
| 75 | + break; |
| 76 | +#endif |
| 77 | #ifdef CONFIG_NET_DSA_TAG_TRAILER |
| 78 | case htons(ETH_P_TRAILER): |
| 79 | slave_dev->netdev_ops = &trailer_netdev_ops; |
| 80 | |