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>
This commit is contained in:
parent
02637fce3e
commit
007f790c82
|
@ -0,0 +1,59 @@
|
|||
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.
|
|
@ -9059,6 +9059,13 @@ F: lib/swiotlb.c
|
|||
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
|
||||
|
|
|
@ -1018,6 +1018,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
|
|||
* 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);
|
||||
|
@ -1171,6 +1177,10 @@ struct net_device_ops {
|
|||
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
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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_ */
|
|
@ -228,6 +228,7 @@ source "net/vmw_vsock/Kconfig"
|
|||
source "net/netlink/Kconfig"
|
||||
source "net/mpls/Kconfig"
|
||||
source "net/hsr/Kconfig"
|
||||
source "net/switchdev/Kconfig"
|
||||
|
||||
config RPS
|
||||
boolean
|
||||
|
|
|
@ -73,3 +73,6 @@ obj-$(CONFIG_OPENVSWITCH) += openvswitch/
|
|||
obj-$(CONFIG_VSOCKETS) += vmw_vsock/
|
||||
obj-$(CONFIG_NET_MPLS_GSO) += mpls/
|
||||
obj-$(CONFIG_HSR) += hsr/
|
||||
ifneq ($(CONFIG_NET_SWITCHDEV),)
|
||||
obj-y += switchdev/
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# 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.
|
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# Makefile for the Switch device API
|
||||
#
|
||||
|
||||
obj-$(CONFIG_NET_SWITCHDEV) += switchdev.o
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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);
|
Loading…
Reference in New Issue