diff options
-rw-r--r-- | Documentation/networking/switchdev.txt | 59 | ||||
-rw-r--r-- | MAINTAINERS | 7 | ||||
-rw-r--r-- | include/linux/netdevice.h | 10 | ||||
-rw-r--r-- | include/net/switchdev.h | 30 | ||||
-rw-r--r-- | net/Kconfig | 1 | ||||
-rw-r--r-- | net/Makefile | 3 | ||||
-rw-r--r-- | net/switchdev/Kconfig | 13 | ||||
-rw-r--r-- | net/switchdev/Makefile | 5 | ||||
-rw-r--r-- | net/switchdev/switchdev.c | 33 |
9 files changed, 161 insertions, 0 deletions
diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt new file mode 100644 index 000000000000..f981a9295a39 --- /dev/null +++ b/Documentation/networking/switchdev.txt | |||
@@ -0,0 +1,59 @@ | |||
1 | Switch (and switch-ish) device drivers HOWTO | ||
2 | =========================== | ||
3 | |||
4 | Please note that the word "switch" is here used in very generic meaning. | ||
5 | This include devices supporting L2/L3 but also various flow offloading chips, | ||
6 | including switches embedded into SR-IOV NICs. | ||
7 | |||
8 | Lets describe a topology a bit. Imagine the following example: | ||
9 | |||
10 | +----------------------------+ +---------------+ | ||
11 | | SOME switch chip | | CPU | | ||
12 | +----------------------------+ +---------------+ | ||
13 | port1 port2 port3 port4 MNGMNT | PCI-E | | ||
14 | | | | | | +---------------+ | ||
15 | PHY PHY | | | | NIC0 NIC1 | ||
16 | | | | | | | | ||
17 | | | +- PCI-E -+ | | | ||
18 | | +------- MII -------+ | | ||
19 | +------------- MII ------------+ | ||
20 | |||
21 | In this example, there are two independent lines between the switch silicon | ||
22 | and CPU. NIC0 and NIC1 drivers are not aware of a switch presence. They are | ||
23 | separate from the switch driver. SOME switch chip is by managed by a driver | ||
24 | via PCI-E device MNGMNT. Note that MNGMNT device, NIC0 and NIC1 may be | ||
25 | connected to some other type of bus. | ||
26 | |||
27 | Now, for the previous example show the representation in kernel: | ||
28 | |||
29 | +----------------------------+ +---------------+ | ||
30 | | SOME switch chip | | CPU | | ||
31 | +----------------------------+ +---------------+ | ||
32 | sw0p0 sw0p1 sw0p2 sw0p3 MNGMNT | PCI-E | | ||
33 | | | | | | +---------------+ | ||
34 | PHY PHY | | | | eth0 eth1 | ||
35 | | | | | | | | ||
36 | | | +- PCI-E -+ | | | ||
37 | | +------- MII -------+ | | ||
38 | +------------- MII ------------+ | ||
39 | |||
40 | Lets call the example switch driver for SOME switch chip "SOMEswitch". This | ||
41 | driver takes care of PCI-E device MNGMNT. There is a netdevice instance sw0pX | ||
42 | created for each port of a switch. These netdevices are instances | ||
43 | of "SOMEswitch" driver. sw0pX netdevices serve as a "representation" | ||
44 | of the switch chip. eth0 and eth1 are instances of some other existing driver. | ||
45 | |||
46 | The only difference of the switch-port netdevice from the ordinary netdevice | ||
47 | is that is implements couple more NDOs: | ||
48 | |||
49 | ndo_switch_parent_id_get - This returns the same ID for two port netdevices | ||
50 | of the same physical switch chip. This is | ||
51 | mandatory to be implemented by all switch drivers | ||
52 | and serves the caller for recognition of a port | ||
53 | netdevice. | ||
54 | ndo_switch_parent_* - Functions that serve for a manipulation of the switch | ||
55 | chip itself (it can be though of as a "parent" of the | ||
56 | port, therefore the name). They are not port-specific. | ||
57 | Caller might use arbitrary port netdevice of the same | ||
58 | switch and it will make no difference. | ||
59 | ndo_switch_port_* - Functions that serve for a port-specific manipulation. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 6b880deae3d2..3aba0ac2d5a3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -9059,6 +9059,13 @@ F: lib/swiotlb.c | |||
9059 | F: arch/*/kernel/pci-swiotlb.c | 9059 | F: arch/*/kernel/pci-swiotlb.c |
9060 | F: include/linux/swiotlb.h | 9060 | F: include/linux/swiotlb.h |
9061 | 9061 | ||
9062 | SWITCHDEV | ||
9063 | M: Jiri Pirko <jiri@resnulli.us> | ||
9064 | L: netdev@vger.kernel.org | ||
9065 | S: Supported | ||
9066 | F: net/switchdev/ | ||
9067 | F: include/net/switchdev.h | ||
9068 | |||
9062 | SYNOPSYS ARC ARCHITECTURE | 9069 | SYNOPSYS ARC ARCHITECTURE |
9063 | M: Vineet Gupta <vgupta@synopsys.com> | 9070 | M: Vineet Gupta <vgupta@synopsys.com> |
9064 | S: Supported | 9071 | S: Supported |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4bd41d72559d..3603f31e78f3 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1018,6 +1018,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, | |||
1018 | * performing GSO on a packet. The device returns true if it is | 1018 | * performing GSO on a packet. The device returns true if it is |
1019 | * able to GSO the packet, false otherwise. If the return value is | 1019 | * able to GSO the packet, false otherwise. If the return value is |
1020 | * false the stack will do software GSO. | 1020 | * false the stack will do software GSO. |
1021 | * | ||
1022 | * int (*ndo_switch_parent_id_get)(struct net_device *dev, | ||
1023 | * struct netdev_phys_item_id *psid); | ||
1024 | * Called to get an ID of the switch chip this port is part of. | ||
1025 | * If driver implements this, it indicates that it represents a port | ||
1026 | * of a switch chip. | ||
1021 | */ | 1027 | */ |
1022 | struct net_device_ops { | 1028 | struct net_device_ops { |
1023 | int (*ndo_init)(struct net_device *dev); | 1029 | int (*ndo_init)(struct net_device *dev); |
@@ -1171,6 +1177,10 @@ struct net_device_ops { | |||
1171 | int (*ndo_get_lock_subclass)(struct net_device *dev); | 1177 | int (*ndo_get_lock_subclass)(struct net_device *dev); |
1172 | bool (*ndo_gso_check) (struct sk_buff *skb, | 1178 | bool (*ndo_gso_check) (struct sk_buff *skb, |
1173 | struct net_device *dev); | 1179 | struct net_device *dev); |
1180 | #ifdef CONFIG_NET_SWITCHDEV | ||
1181 | int (*ndo_switch_parent_id_get)(struct net_device *dev, | ||
1182 | struct netdev_phys_item_id *psid); | ||
1183 | #endif | ||
1174 | }; | 1184 | }; |
1175 | 1185 | ||
1176 | /** | 1186 | /** |
diff --git a/include/net/switchdev.h b/include/net/switchdev.h new file mode 100644 index 000000000000..7a52360a1446 --- /dev/null +++ b/include/net/switchdev.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * include/net/switchdev.h - Switch device API | ||
3 | * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | */ | ||
10 | #ifndef _LINUX_SWITCHDEV_H_ | ||
11 | #define _LINUX_SWITCHDEV_H_ | ||
12 | |||
13 | #include <linux/netdevice.h> | ||
14 | |||
15 | #ifdef CONFIG_NET_SWITCHDEV | ||
16 | |||
17 | int netdev_switch_parent_id_get(struct net_device *dev, | ||
18 | struct netdev_phys_item_id *psid); | ||
19 | |||
20 | #else | ||
21 | |||
22 | static inline int netdev_switch_parent_id_get(struct net_device *dev, | ||
23 | struct netdev_phys_item_id *psid) | ||
24 | { | ||
25 | return -EOPNOTSUPP; | ||
26 | } | ||
27 | |||
28 | #endif | ||
29 | |||
30 | #endif /* _LINUX_SWITCHDEV_H_ */ | ||
diff --git a/net/Kconfig b/net/Kconfig index 99815b5454bf..ff9ffc17fa0e 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
@@ -228,6 +228,7 @@ source "net/vmw_vsock/Kconfig" | |||
228 | source "net/netlink/Kconfig" | 228 | source "net/netlink/Kconfig" |
229 | source "net/mpls/Kconfig" | 229 | source "net/mpls/Kconfig" |
230 | source "net/hsr/Kconfig" | 230 | source "net/hsr/Kconfig" |
231 | source "net/switchdev/Kconfig" | ||
231 | 232 | ||
232 | config RPS | 233 | config RPS |
233 | boolean | 234 | boolean |
diff --git a/net/Makefile b/net/Makefile index 7ed1970074b0..95fc694e4ddc 100644 --- a/net/Makefile +++ b/net/Makefile | |||
@@ -73,3 +73,6 @@ obj-$(CONFIG_OPENVSWITCH) += openvswitch/ | |||
73 | obj-$(CONFIG_VSOCKETS) += vmw_vsock/ | 73 | obj-$(CONFIG_VSOCKETS) += vmw_vsock/ |
74 | obj-$(CONFIG_NET_MPLS_GSO) += mpls/ | 74 | obj-$(CONFIG_NET_MPLS_GSO) += mpls/ |
75 | obj-$(CONFIG_HSR) += hsr/ | 75 | obj-$(CONFIG_HSR) += hsr/ |
76 | ifneq ($(CONFIG_NET_SWITCHDEV),) | ||
77 | obj-y += switchdev/ | ||
78 | endif | ||
diff --git a/net/switchdev/Kconfig b/net/switchdev/Kconfig new file mode 100644 index 000000000000..155754588fd6 --- /dev/null +++ b/net/switchdev/Kconfig | |||
@@ -0,0 +1,13 @@ | |||
1 | # | ||
2 | # Configuration for Switch device support | ||
3 | # | ||
4 | |||
5 | config NET_SWITCHDEV | ||
6 | boolean "Switch (and switch-ish) device support (EXPERIMENTAL)" | ||
7 | depends on INET | ||
8 | ---help--- | ||
9 | This module provides glue between core networking code and device | ||
10 | drivers in order to support hardware switch chips in very generic | ||
11 | meaning of the word "switch". This include devices supporting L2/L3 but | ||
12 | also various flow offloading chips, including switches embedded into | ||
13 | SR-IOV NICs. | ||
diff --git a/net/switchdev/Makefile b/net/switchdev/Makefile new file mode 100644 index 000000000000..5ed63ed324d0 --- /dev/null +++ b/net/switchdev/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Makefile for the Switch device API | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_NET_SWITCHDEV) += switchdev.o | ||
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c new file mode 100644 index 000000000000..66973deaae56 --- /dev/null +++ b/net/switchdev/switchdev.c | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * net/switchdev/switchdev.c - Switch device API | ||
3 | * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/netdevice.h> | ||
15 | #include <net/switchdev.h> | ||
16 | |||
17 | /** | ||
18 | * netdev_switch_parent_id_get - Get ID of a switch | ||
19 | * @dev: port device | ||
20 | * @psid: switch ID | ||
21 | * | ||
22 | * Get ID of a switch this port is part of. | ||
23 | */ | ||
24 | int netdev_switch_parent_id_get(struct net_device *dev, | ||
25 | struct netdev_phys_item_id *psid) | ||
26 | { | ||
27 | const struct net_device_ops *ops = dev->netdev_ops; | ||
28 | |||
29 | if (!ops->ndo_switch_parent_id_get) | ||
30 | return -EOPNOTSUPP; | ||
31 | return ops->ndo_switch_parent_id_get(dev, psid); | ||
32 | } | ||
33 | EXPORT_SYMBOL(netdev_switch_parent_id_get); | ||