Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: introduce generic switch devices support

The goal of this is to provide a possibility to support various switch
chips. Drivers should implement relevant ndos to do so. Now there is
only one ndo defined:
- for getting physical switch id is in place.

Note that user can use random port netdevice to access the switch.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Reviewed-by: Thomas Graf <tgraf@suug.ch>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jiri Pirko and committed by
David S. Miller
007f790c 02637fce

+161
+59
Documentation/networking/switchdev.txt
··· 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.
+7
MAINTAINERS
··· 9059 9059 F: arch/*/kernel/pci-swiotlb.c 9060 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 9069 SYNOPSYS ARC ARCHITECTURE 9063 9070 M: Vineet Gupta <vgupta@synopsys.com> 9064 9071 S: Supported
+10
include/linux/netdevice.h
··· 1018 1018 * performing GSO on a packet. The device returns true if it is 1019 1019 * able to GSO the packet, false otherwise. If the return value is 1020 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 1028 struct net_device_ops { 1023 1029 int (*ndo_init)(struct net_device *dev); ··· 1177 1171 int (*ndo_get_lock_subclass)(struct net_device *dev); 1178 1172 bool (*ndo_gso_check) (struct sk_buff *skb, 1179 1173 struct net_device *dev); 1174 + #ifdef CONFIG_NET_SWITCHDEV 1175 + int (*ndo_switch_parent_id_get)(struct net_device *dev, 1176 + struct netdev_phys_item_id *psid); 1177 + #endif 1180 1178 }; 1181 1179 1182 1180 /**
+30
include/net/switchdev.h
··· 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_ */
+1
net/Kconfig
··· 228 228 source "net/netlink/Kconfig" 229 229 source "net/mpls/Kconfig" 230 230 source "net/hsr/Kconfig" 231 + source "net/switchdev/Kconfig" 231 232 232 233 config RPS 233 234 boolean
+3
net/Makefile
··· 73 73 obj-$(CONFIG_VSOCKETS) += vmw_vsock/ 74 74 obj-$(CONFIG_NET_MPLS_GSO) += mpls/ 75 75 obj-$(CONFIG_HSR) += hsr/ 76 + ifneq ($(CONFIG_NET_SWITCHDEV),) 77 + obj-y += switchdev/ 78 + endif
+13
net/switchdev/Kconfig
··· 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.
+5
net/switchdev/Makefile
··· 1 + # 2 + # Makefile for the Switch device API 3 + # 4 + 5 + obj-$(CONFIG_NET_SWITCHDEV) += switchdev.o
+33
net/switchdev/switchdev.c
··· 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);