1421 lines · 42.3 KB · C
RawDownload
/* SPDX-License-Identifier: GPL-2.0-or-later *//* * include/net/dsa.h - Driver for Distributed Switch Architecture switch chips * Copyright (c) 2008-2009 Marvell Semiconductor */ #ifndef __LINUX_NET_DSA_H#define __LINUX_NET_DSA_H #include <linux/if.h>#include <linux/if_ether.h>#include <linux/list.h>#include <linux/notifier.h>#include <linux/timer.h>#include <linux/workqueue.h>#include <linux/of.h>#include <linux/ethtool.h>#include <linux/net_tstamp.h>#include <linux/phy.h>#include <linux/platform_data/dsa.h>#include <linux/phylink.h>#include <net/devlink.h>#include <net/switchdev.h> struct dsa_8021q_context;struct tc_action; #define DSA_TAG_PROTO_NONE_VALUE		0#define DSA_TAG_PROTO_BRCM_VALUE		1#define DSA_TAG_PROTO_BRCM_PREPEND_VALUE	2#define DSA_TAG_PROTO_DSA_VALUE			3#define DSA_TAG_PROTO_EDSA_VALUE		4#define DSA_TAG_PROTO_GSWIP_VALUE		5#define DSA_TAG_PROTO_KSZ9477_VALUE		6#define DSA_TAG_PROTO_KSZ9893_VALUE		7#define DSA_TAG_PROTO_LAN9303_VALUE		8#define DSA_TAG_PROTO_MTK_VALUE			9#define DSA_TAG_PROTO_QCA_VALUE			10#define DSA_TAG_PROTO_TRAILER_VALUE		11#define DSA_TAG_PROTO_8021Q_VALUE		12#define DSA_TAG_PROTO_SJA1105_VALUE		13#define DSA_TAG_PROTO_KSZ8795_VALUE		14#define DSA_TAG_PROTO_OCELOT_VALUE		15#define DSA_TAG_PROTO_AR9331_VALUE		16#define DSA_TAG_PROTO_RTL4_A_VALUE		17#define DSA_TAG_PROTO_HELLCREEK_VALUE		18#define DSA_TAG_PROTO_XRS700X_VALUE		19#define DSA_TAG_PROTO_OCELOT_8021Q_VALUE	20#define DSA_TAG_PROTO_SEVILLE_VALUE		21#define DSA_TAG_PROTO_BRCM_LEGACY_VALUE		22#define DSA_TAG_PROTO_SJA1110_VALUE		23#define DSA_TAG_PROTO_RTL8_4_VALUE		24#define DSA_TAG_PROTO_RTL8_4T_VALUE		25#define DSA_TAG_PROTO_RZN1_A5PSW_VALUE		26#define DSA_TAG_PROTO_LAN937X_VALUE		27#define DSA_TAG_PROTO_VSC73XX_8021Q_VALUE	28#define DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE	29#define DSA_TAG_PROTO_YT921X_VALUE		30#define DSA_TAG_PROTO_MXL_GSW1XX_VALUE		31#define DSA_TAG_PROTO_MXL862_VALUE		32#define DSA_TAG_PROTO_NETC_VALUE		33#define DSA_TAG_PROTO_KSZ8463_VALUE		34#define DSA_TAG_PROTO_MT7628_VALUE		35 enum dsa_tag_protocol {	DSA_TAG_PROTO_NONE		= DSA_TAG_PROTO_NONE_VALUE,	DSA_TAG_PROTO_BRCM		= DSA_TAG_PROTO_BRCM_VALUE,	DSA_TAG_PROTO_BRCM_LEGACY	= DSA_TAG_PROTO_BRCM_LEGACY_VALUE,	DSA_TAG_PROTO_BRCM_LEGACY_FCS	= DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE,	DSA_TAG_PROTO_BRCM_PREPEND	= DSA_TAG_PROTO_BRCM_PREPEND_VALUE,	DSA_TAG_PROTO_DSA		= DSA_TAG_PROTO_DSA_VALUE,	DSA_TAG_PROTO_EDSA		= DSA_TAG_PROTO_EDSA_VALUE,	DSA_TAG_PROTO_GSWIP		= DSA_TAG_PROTO_GSWIP_VALUE,	DSA_TAG_PROTO_KSZ9477		= DSA_TAG_PROTO_KSZ9477_VALUE,	DSA_TAG_PROTO_KSZ9893		= DSA_TAG_PROTO_KSZ9893_VALUE,	DSA_TAG_PROTO_LAN9303		= DSA_TAG_PROTO_LAN9303_VALUE,	DSA_TAG_PROTO_MTK		= DSA_TAG_PROTO_MTK_VALUE,	DSA_TAG_PROTO_QCA		= DSA_TAG_PROTO_QCA_VALUE,	DSA_TAG_PROTO_TRAILER		= DSA_TAG_PROTO_TRAILER_VALUE,	DSA_TAG_PROTO_8021Q		= DSA_TAG_PROTO_8021Q_VALUE,	DSA_TAG_PROTO_SJA1105		= DSA_TAG_PROTO_SJA1105_VALUE,	DSA_TAG_PROTO_KSZ8795		= DSA_TAG_PROTO_KSZ8795_VALUE,	DSA_TAG_PROTO_OCELOT		= DSA_TAG_PROTO_OCELOT_VALUE,	DSA_TAG_PROTO_AR9331		= DSA_TAG_PROTO_AR9331_VALUE,	DSA_TAG_PROTO_RTL4_A		= DSA_TAG_PROTO_RTL4_A_VALUE,	DSA_TAG_PROTO_HELLCREEK		= DSA_TAG_PROTO_HELLCREEK_VALUE,	DSA_TAG_PROTO_XRS700X		= DSA_TAG_PROTO_XRS700X_VALUE,	DSA_TAG_PROTO_OCELOT_8021Q	= DSA_TAG_PROTO_OCELOT_8021Q_VALUE,	DSA_TAG_PROTO_SEVILLE		= DSA_TAG_PROTO_SEVILLE_VALUE,	DSA_TAG_PROTO_SJA1110		= DSA_TAG_PROTO_SJA1110_VALUE,	DSA_TAG_PROTO_RTL8_4		= DSA_TAG_PROTO_RTL8_4_VALUE,	DSA_TAG_PROTO_RTL8_4T		= DSA_TAG_PROTO_RTL8_4T_VALUE,	DSA_TAG_PROTO_RZN1_A5PSW	= DSA_TAG_PROTO_RZN1_A5PSW_VALUE,	DSA_TAG_PROTO_LAN937X		= DSA_TAG_PROTO_LAN937X_VALUE,	DSA_TAG_PROTO_VSC73XX_8021Q	= DSA_TAG_PROTO_VSC73XX_8021Q_VALUE,	DSA_TAG_PROTO_YT921X		= DSA_TAG_PROTO_YT921X_VALUE,	DSA_TAG_PROTO_MXL_GSW1XX	= DSA_TAG_PROTO_MXL_GSW1XX_VALUE,	DSA_TAG_PROTO_MXL862		= DSA_TAG_PROTO_MXL862_VALUE,	DSA_TAG_PROTO_NETC		= DSA_TAG_PROTO_NETC_VALUE,	DSA_TAG_PROTO_KSZ8463		= DSA_TAG_PROTO_KSZ8463_VALUE,	DSA_TAG_PROTO_MT7628		= DSA_TAG_PROTO_MT7628_VALUE,}; struct dsa_switch; struct dsa_device_ops {	struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);	struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev);	void (*flow_dissect)(const struct sk_buff *skb, __be16 *proto,			     int *offset);	int (*connect)(struct dsa_switch *ds);	void (*disconnect)(struct dsa_switch *ds);	unsigned int needed_headroom;	unsigned int needed_tailroom;	const char *name;	enum dsa_tag_protocol proto;	/* Some tagging protocols either mangle or shift the destination MAC	 * address, in which case the DSA conduit would drop packets on ingress	 * if what it understands out of the destination MAC address is not in	 * its RX filter.	 */	bool promisc_on_conduit;}; struct dsa_lag {	struct net_device *dev;	unsigned int id;	struct mutex fdb_lock;	struct list_head fdbs;	refcount_t refcount;}; struct dsa_switch_tree {	struct list_head	list; 	/* List of switch ports */	struct list_head ports; 	/* Notifier chain for switch-wide events */	struct raw_notifier_head	nh; 	/* Tree identifier */	unsigned int index; 	/* Number of switches attached to this tree */	struct kref refcount; 	/* Maps offloaded LAG netdevs to a zero-based linear ID for	 * drivers that need it.	 */	struct dsa_lag **lags; 	/* Tagging protocol operations */	const struct dsa_device_ops *tag_ops; 	/* Default tagging protocol preferred by the switches in this	 * tree.	 */	enum dsa_tag_protocol default_proto; 	/* Has this tree been applied to the hardware? */	bool setup; 	/*	 * Configuration data for the platform device that owns	 * this dsa switch tree instance.	 */	struct dsa_platform_data	*pd; 	/* List of DSA links composing the routing table */	struct list_head rtable; 	/* Length of "lags" array */	unsigned int lags_len; 	/* Track the largest switch index within a tree */	unsigned int last_switch;}; /* LAG IDs are one-based, the dst->lags array is zero-based */#define dsa_lags_foreach_id(_id, _dst)				\	for ((_id) = 1; (_id) <= (_dst)->lags_len; (_id)++)	\		if ((_dst)->lags[(_id) - 1]) #define dsa_lag_foreach_port(_dp, _dst, _lag)			\	list_for_each_entry((_dp), &(_dst)->ports, list)	\		if (dsa_port_offloads_lag((_dp), (_lag))) #define dsa_hsr_foreach_port(_dp, _ds, _hsr)			\	list_for_each_entry((_dp), &(_ds)->dst->ports, list)	\		if ((_dp)->ds == (_ds) && (_dp)->hsr_dev == (_hsr)) static inline struct dsa_lag *dsa_lag_by_id(struct dsa_switch_tree *dst,					    unsigned int id){	/* DSA LAG IDs are one-based, dst->lags is zero-based */	return dst->lags[id - 1];} static inline int dsa_lag_id(struct dsa_switch_tree *dst,			     struct net_device *lag_dev){	unsigned int id; 	dsa_lags_foreach_id(id, dst) {		struct dsa_lag *lag = dsa_lag_by_id(dst, id); 		if (lag->dev == lag_dev)			return lag->id;	} 	return -ENODEV;} /* TC matchall action types */enum dsa_port_mall_action_type {	DSA_PORT_MALL_MIRROR,	DSA_PORT_MALL_POLICER,}; /* TC mirroring entry */struct dsa_mall_mirror_tc_entry {	u8 to_local_port;	bool ingress;}; /* TC matchall entry */struct dsa_mall_tc_entry {	struct list_head list;	unsigned long cookie;	enum dsa_port_mall_action_type type;	union {		struct dsa_mall_mirror_tc_entry mirror;		struct flow_action_police policer;	};}; struct dsa_bridge {	struct net_device *dev;	unsigned int num;	bool tx_fwd_offload;	refcount_t refcount;}; struct dsa_port {	/* A CPU port is physically connected to a conduit device. A user port	 * exposes a network device to user-space, called 'user' here.	 */	union {		struct net_device *conduit;		struct net_device *user;	}; 	/* Copy of the tagging protocol operations, for quicker access	 * in the data path. Valid only for the CPU ports.	 */	const struct dsa_device_ops *tag_ops; 	/* Copies for faster access in conduit receive hot path */	struct dsa_switch_tree *dst;	struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev); 	struct dsa_switch	*ds; 	unsigned int		index; 	enum {		DSA_PORT_TYPE_UNUSED = 0,		DSA_PORT_TYPE_CPU,		DSA_PORT_TYPE_DSA,		DSA_PORT_TYPE_USER,	} type; 	const char		*name;	struct dsa_port		*cpu_dp;	u8			mac[ETH_ALEN]; 	u8			stp_state; 	/* Warning: the following bit fields are not atomic, and updating them	 * can only be done from code paths where concurrency is not possible	 * (probe time or under rtnl_lock).	 */	u8			vlan_filtering:1; 	/* Managed by DSA on user ports and by drivers on CPU and DSA ports */	u8			learning:1; 	u8			lag_tx_enabled:1; 	/* conduit state bits, valid only on CPU ports */	u8			conduit_admin_up:1;	u8			conduit_oper_up:1; 	/* Valid only on user ports */	u8			cpu_port_in_lag:1; 	u8			setup:1; 	struct device_node	*dn;	unsigned int		ageing_time; 	struct dsa_bridge	*bridge;	struct devlink_port	devlink_port;	struct phylink		*pl;	struct phylink_config	pl_config;	netdevice_tracker	conduit_tracker;	struct dsa_lag		*lag;	struct net_device	*hsr_dev; 	struct list_head list; 	/*	 * Original copy of the conduit netdev ethtool_ops	 */	const struct ethtool_ops *orig_ethtool_ops; 	/* List of MAC addresses that must be forwarded on this port.	 * These are only valid on CPU ports and DSA links.	 */	struct mutex		addr_lists_lock;	struct list_head	fdbs;	struct list_head	mdbs; 	struct mutex		vlans_lock;	union {		/* List of VLANs that CPU and DSA ports are members of.		 * Access to this is serialized by the sleepable @vlans_lock.		 */		struct list_head	vlans;		/* List of VLANs that user ports are members of.		 * Access to this is serialized by netif_addr_lock_bh().		 */		struct list_head	user_vlans;	};}; static inline struct dsa_port *dsa_phylink_to_port(struct phylink_config *config){	return container_of(config, struct dsa_port, pl_config);} /* TODO: ideally DSA ports would have a single dp->link_dp member, * and no dst->rtable nor this struct dsa_link would be needed, * but this would require some more complex tree walking, * so keep it stupid at the moment and list them all. */struct dsa_link {	struct dsa_port *dp;	struct dsa_port *link_dp;	struct list_head list;}; enum dsa_db_type {	DSA_DB_PORT,	DSA_DB_LAG,	DSA_DB_BRIDGE,}; struct dsa_db {	enum dsa_db_type type; 	union {		const struct dsa_port *dp;		struct dsa_lag lag;		struct dsa_bridge bridge;	};}; struct dsa_mac_addr {	unsigned char addr[ETH_ALEN];	u16 vid;	refcount_t refcount;	struct list_head list;	struct dsa_db db;}; struct dsa_vlan {	u16 vid;	refcount_t refcount;	struct list_head list;}; struct dsa_switch {	struct device *dev; 	/*	 * Parent switch tree, and switch index.	 */	struct dsa_switch_tree	*dst;	unsigned int		index; 	/* Warning: the following bit fields are not atomic, and updating them	 * can only be done from code paths where concurrency is not possible	 * (probe time or under rtnl_lock).	 */	u32			setup:1; 	/* Disallow bridge core from requesting different VLAN awareness	 * settings on ports if not hardware-supported	 */	u32			vlan_filtering_is_global:1; 	/* Keep VLAN filtering enabled on ports not offloading any upper */	u32			needs_standalone_vlan_filtering:1; 	/* Pass .port_vlan_add and .port_vlan_del to drivers even for bridges	 * that have vlan_filtering=0. All drivers should ideally set this (and	 * then the option would get removed), but it is unknown whether this	 * would break things or not.	 */	u32			configure_vlan_while_not_filtering:1; 	/* Pop the default_pvid of VLAN-unaware bridge ports from tagged frames.	 * DEPRECATED: Do NOT set this field in new drivers. Instead look at	 * the dsa_software_vlan_untag() comments.	 */	u32			untag_bridge_pvid:1;	/* Pop the default_pvid of VLAN-aware bridge ports from tagged frames.	 * Useful if the switch cannot preserve the VLAN tag as seen on the	 * wire for user port ingress, and chooses to send all frames as	 * VLAN-tagged to the CPU, including those which were originally	 * untagged.	 */	u32			untag_vlan_aware_bridge_pvid:1; 	/* Let DSA manage the FDB entries towards the	 * CPU, based on the software bridge database.	 */	u32			assisted_learning_on_cpu_port:1; 	/* In case vlan_filtering_is_global is set, the VLAN awareness state	 * should be retrieved from here and not from the per-port settings.	 */	u32			vlan_filtering:1; 	/* For switches that only have the MRU configurable. To ensure the	 * configured MTU is not exceeded, normalization of MRU on all bridged	 * interfaces is needed.	 */	u32			mtu_enforcement_ingress:1; 	/* Drivers that isolate the FDBs of multiple bridges must set this	 * to true to receive the bridge as an argument in .port_fdb_{add,del}	 * and .port_mdb_{add,del}. Otherwise, the bridge.num will always be	 * passed as zero.	 */	u32			fdb_isolation:1; 	/* Drivers that have global DSCP mapping settings must set this to	 * true to automatically apply the settings to all ports.	 */	u32			dscp_prio_mapping_is_global:1; 	/* Listener for switch fabric events */	struct notifier_block	nb; 	/*	 * Give the switch driver somewhere to hang its private data	 * structure.	 */	void *priv; 	void *tagger_data; 	/*	 * Configuration data for this switch.	 */	struct dsa_chip_data	*cd; 	/*	 * The switch operations.	 */	const struct dsa_switch_ops	*ops; 	/*	 * Allow a DSA switch driver to override the phylink MAC ops	 */	const struct phylink_mac_ops	*phylink_mac_ops; 	/*	 * User mii_bus and devices for the individual ports.	 */	u32			phys_mii_mask;	struct mii_bus		*user_mii_bus; 	/* Ageing Time limits in msecs */	unsigned int ageing_time_min;	unsigned int ageing_time_max; 	/* Storage for drivers using tag_8021q */	struct dsa_8021q_context *tag_8021q_ctx; 	/* devlink used to represent this switch device */	struct devlink		*devlink; 	/* Number of switch port queues */	unsigned int		num_tx_queues; 

Lines 1–500 of 1421.