xref: /OK3568_Linux_fs/kernel/include/net/dsa.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * include/net/dsa.h - Driver for Distributed Switch Architecture switch chips
4*4882a593Smuzhiyun  * Copyright (c) 2008-2009 Marvell Semiconductor
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #ifndef __LINUX_NET_DSA_H
8*4882a593Smuzhiyun #define __LINUX_NET_DSA_H
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/if.h>
11*4882a593Smuzhiyun #include <linux/if_ether.h>
12*4882a593Smuzhiyun #include <linux/list.h>
13*4882a593Smuzhiyun #include <linux/notifier.h>
14*4882a593Smuzhiyun #include <linux/timer.h>
15*4882a593Smuzhiyun #include <linux/workqueue.h>
16*4882a593Smuzhiyun #include <linux/of.h>
17*4882a593Smuzhiyun #include <linux/ethtool.h>
18*4882a593Smuzhiyun #include <linux/net_tstamp.h>
19*4882a593Smuzhiyun #include <linux/phy.h>
20*4882a593Smuzhiyun #include <linux/platform_data/dsa.h>
21*4882a593Smuzhiyun #include <linux/phylink.h>
22*4882a593Smuzhiyun #include <net/devlink.h>
23*4882a593Smuzhiyun #include <net/switchdev.h>
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun struct tc_action;
26*4882a593Smuzhiyun struct phy_device;
27*4882a593Smuzhiyun struct fixed_phy_status;
28*4882a593Smuzhiyun struct phylink_link_state;
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define DSA_TAG_PROTO_NONE_VALUE		0
31*4882a593Smuzhiyun #define DSA_TAG_PROTO_BRCM_VALUE		1
32*4882a593Smuzhiyun #define DSA_TAG_PROTO_BRCM_PREPEND_VALUE	2
33*4882a593Smuzhiyun #define DSA_TAG_PROTO_DSA_VALUE			3
34*4882a593Smuzhiyun #define DSA_TAG_PROTO_EDSA_VALUE		4
35*4882a593Smuzhiyun #define DSA_TAG_PROTO_GSWIP_VALUE		5
36*4882a593Smuzhiyun #define DSA_TAG_PROTO_KSZ9477_VALUE		6
37*4882a593Smuzhiyun #define DSA_TAG_PROTO_KSZ9893_VALUE		7
38*4882a593Smuzhiyun #define DSA_TAG_PROTO_LAN9303_VALUE		8
39*4882a593Smuzhiyun #define DSA_TAG_PROTO_MTK_VALUE			9
40*4882a593Smuzhiyun #define DSA_TAG_PROTO_QCA_VALUE			10
41*4882a593Smuzhiyun #define DSA_TAG_PROTO_TRAILER_VALUE		11
42*4882a593Smuzhiyun #define DSA_TAG_PROTO_8021Q_VALUE		12
43*4882a593Smuzhiyun #define DSA_TAG_PROTO_SJA1105_VALUE		13
44*4882a593Smuzhiyun #define DSA_TAG_PROTO_KSZ8795_VALUE		14
45*4882a593Smuzhiyun #define DSA_TAG_PROTO_OCELOT_VALUE		15
46*4882a593Smuzhiyun #define DSA_TAG_PROTO_AR9331_VALUE		16
47*4882a593Smuzhiyun #define DSA_TAG_PROTO_RTL4_A_VALUE		17
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun enum dsa_tag_protocol {
50*4882a593Smuzhiyun 	DSA_TAG_PROTO_NONE		= DSA_TAG_PROTO_NONE_VALUE,
51*4882a593Smuzhiyun 	DSA_TAG_PROTO_BRCM		= DSA_TAG_PROTO_BRCM_VALUE,
52*4882a593Smuzhiyun 	DSA_TAG_PROTO_BRCM_PREPEND	= DSA_TAG_PROTO_BRCM_PREPEND_VALUE,
53*4882a593Smuzhiyun 	DSA_TAG_PROTO_DSA		= DSA_TAG_PROTO_DSA_VALUE,
54*4882a593Smuzhiyun 	DSA_TAG_PROTO_EDSA		= DSA_TAG_PROTO_EDSA_VALUE,
55*4882a593Smuzhiyun 	DSA_TAG_PROTO_GSWIP		= DSA_TAG_PROTO_GSWIP_VALUE,
56*4882a593Smuzhiyun 	DSA_TAG_PROTO_KSZ9477		= DSA_TAG_PROTO_KSZ9477_VALUE,
57*4882a593Smuzhiyun 	DSA_TAG_PROTO_KSZ9893		= DSA_TAG_PROTO_KSZ9893_VALUE,
58*4882a593Smuzhiyun 	DSA_TAG_PROTO_LAN9303		= DSA_TAG_PROTO_LAN9303_VALUE,
59*4882a593Smuzhiyun 	DSA_TAG_PROTO_MTK		= DSA_TAG_PROTO_MTK_VALUE,
60*4882a593Smuzhiyun 	DSA_TAG_PROTO_QCA		= DSA_TAG_PROTO_QCA_VALUE,
61*4882a593Smuzhiyun 	DSA_TAG_PROTO_TRAILER		= DSA_TAG_PROTO_TRAILER_VALUE,
62*4882a593Smuzhiyun 	DSA_TAG_PROTO_8021Q		= DSA_TAG_PROTO_8021Q_VALUE,
63*4882a593Smuzhiyun 	DSA_TAG_PROTO_SJA1105		= DSA_TAG_PROTO_SJA1105_VALUE,
64*4882a593Smuzhiyun 	DSA_TAG_PROTO_KSZ8795		= DSA_TAG_PROTO_KSZ8795_VALUE,
65*4882a593Smuzhiyun 	DSA_TAG_PROTO_OCELOT		= DSA_TAG_PROTO_OCELOT_VALUE,
66*4882a593Smuzhiyun 	DSA_TAG_PROTO_AR9331		= DSA_TAG_PROTO_AR9331_VALUE,
67*4882a593Smuzhiyun 	DSA_TAG_PROTO_RTL4_A		= DSA_TAG_PROTO_RTL4_A_VALUE,
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun struct packet_type;
71*4882a593Smuzhiyun struct dsa_switch;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun struct dsa_device_ops {
74*4882a593Smuzhiyun 	struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
75*4882a593Smuzhiyun 	struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev,
76*4882a593Smuzhiyun 			       struct packet_type *pt);
77*4882a593Smuzhiyun 	void (*flow_dissect)(const struct sk_buff *skb, __be16 *proto,
78*4882a593Smuzhiyun 			     int *offset);
79*4882a593Smuzhiyun 	/* Used to determine which traffic should match the DSA filter in
80*4882a593Smuzhiyun 	 * eth_type_trans, and which, if any, should bypass it and be processed
81*4882a593Smuzhiyun 	 * as regular on the master net device.
82*4882a593Smuzhiyun 	 */
83*4882a593Smuzhiyun 	bool (*filter)(const struct sk_buff *skb, struct net_device *dev);
84*4882a593Smuzhiyun 	unsigned int overhead;
85*4882a593Smuzhiyun 	const char *name;
86*4882a593Smuzhiyun 	enum dsa_tag_protocol proto;
87*4882a593Smuzhiyun 	/* Some tagging protocols either mangle or shift the destination MAC
88*4882a593Smuzhiyun 	 * address, in which case the DSA master would drop packets on ingress
89*4882a593Smuzhiyun 	 * if what it understands out of the destination MAC address is not in
90*4882a593Smuzhiyun 	 * its RX filter.
91*4882a593Smuzhiyun 	 */
92*4882a593Smuzhiyun 	bool promisc_on_master;
93*4882a593Smuzhiyun 	bool tail_tag;
94*4882a593Smuzhiyun };
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun /* This structure defines the control interfaces that are overlayed by the
97*4882a593Smuzhiyun  * DSA layer on top of the DSA CPU/management net_device instance. This is
98*4882a593Smuzhiyun  * used by the core net_device layer while calling various net_device_ops
99*4882a593Smuzhiyun  * function pointers.
100*4882a593Smuzhiyun  */
101*4882a593Smuzhiyun struct dsa_netdevice_ops {
102*4882a593Smuzhiyun 	int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr,
103*4882a593Smuzhiyun 			    int cmd);
104*4882a593Smuzhiyun };
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun #define DSA_TAG_DRIVER_ALIAS "dsa_tag-"
107*4882a593Smuzhiyun #define MODULE_ALIAS_DSA_TAG_DRIVER(__proto)				\
108*4882a593Smuzhiyun 	MODULE_ALIAS(DSA_TAG_DRIVER_ALIAS __stringify(__proto##_VALUE))
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun struct dsa_skb_cb {
111*4882a593Smuzhiyun 	struct sk_buff *clone;
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun struct __dsa_skb_cb {
115*4882a593Smuzhiyun 	struct dsa_skb_cb cb;
116*4882a593Smuzhiyun 	u8 priv[48 - sizeof(struct dsa_skb_cb)];
117*4882a593Smuzhiyun };
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun #define DSA_SKB_CB(skb) ((struct dsa_skb_cb *)((skb)->cb))
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun #define DSA_SKB_CB_PRIV(skb)			\
122*4882a593Smuzhiyun 	((void *)(skb)->cb + offsetof(struct __dsa_skb_cb, priv))
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun struct dsa_switch_tree {
125*4882a593Smuzhiyun 	struct list_head	list;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	/* Notifier chain for switch-wide events */
128*4882a593Smuzhiyun 	struct raw_notifier_head	nh;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	/* Tree identifier */
131*4882a593Smuzhiyun 	unsigned int index;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	/* Number of switches attached to this tree */
134*4882a593Smuzhiyun 	struct kref refcount;
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	/* Has this tree been applied to the hardware? */
137*4882a593Smuzhiyun 	bool setup;
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	/*
140*4882a593Smuzhiyun 	 * Configuration data for the platform device that owns
141*4882a593Smuzhiyun 	 * this dsa switch tree instance.
142*4882a593Smuzhiyun 	 */
143*4882a593Smuzhiyun 	struct dsa_platform_data	*pd;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	/* List of switch ports */
146*4882a593Smuzhiyun 	struct list_head ports;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	/* List of DSA links composing the routing table */
149*4882a593Smuzhiyun 	struct list_head rtable;
150*4882a593Smuzhiyun };
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun /* TC matchall action types */
153*4882a593Smuzhiyun enum dsa_port_mall_action_type {
154*4882a593Smuzhiyun 	DSA_PORT_MALL_MIRROR,
155*4882a593Smuzhiyun 	DSA_PORT_MALL_POLICER,
156*4882a593Smuzhiyun };
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun /* TC mirroring entry */
159*4882a593Smuzhiyun struct dsa_mall_mirror_tc_entry {
160*4882a593Smuzhiyun 	u8 to_local_port;
161*4882a593Smuzhiyun 	bool ingress;
162*4882a593Smuzhiyun };
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun /* TC port policer entry */
165*4882a593Smuzhiyun struct dsa_mall_policer_tc_entry {
166*4882a593Smuzhiyun 	u32 burst;
167*4882a593Smuzhiyun 	u64 rate_bytes_per_sec;
168*4882a593Smuzhiyun };
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun /* TC matchall entry */
171*4882a593Smuzhiyun struct dsa_mall_tc_entry {
172*4882a593Smuzhiyun 	struct list_head list;
173*4882a593Smuzhiyun 	unsigned long cookie;
174*4882a593Smuzhiyun 	enum dsa_port_mall_action_type type;
175*4882a593Smuzhiyun 	union {
176*4882a593Smuzhiyun 		struct dsa_mall_mirror_tc_entry mirror;
177*4882a593Smuzhiyun 		struct dsa_mall_policer_tc_entry policer;
178*4882a593Smuzhiyun 	};
179*4882a593Smuzhiyun };
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun struct dsa_port {
183*4882a593Smuzhiyun 	/* A CPU port is physically connected to a master device.
184*4882a593Smuzhiyun 	 * A user port exposed to userspace has a slave device.
185*4882a593Smuzhiyun 	 */
186*4882a593Smuzhiyun 	union {
187*4882a593Smuzhiyun 		struct net_device *master;
188*4882a593Smuzhiyun 		struct net_device *slave;
189*4882a593Smuzhiyun 	};
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	/* CPU port tagging operations used by master or slave devices */
192*4882a593Smuzhiyun 	const struct dsa_device_ops *tag_ops;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	/* Copies for faster access in master receive hot path */
195*4882a593Smuzhiyun 	struct dsa_switch_tree *dst;
196*4882a593Smuzhiyun 	struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev,
197*4882a593Smuzhiyun 			       struct packet_type *pt);
198*4882a593Smuzhiyun 	bool (*filter)(const struct sk_buff *skb, struct net_device *dev);
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	enum {
201*4882a593Smuzhiyun 		DSA_PORT_TYPE_UNUSED = 0,
202*4882a593Smuzhiyun 		DSA_PORT_TYPE_CPU,
203*4882a593Smuzhiyun 		DSA_PORT_TYPE_DSA,
204*4882a593Smuzhiyun 		DSA_PORT_TYPE_USER,
205*4882a593Smuzhiyun 	} type;
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	struct dsa_switch	*ds;
208*4882a593Smuzhiyun 	unsigned int		index;
209*4882a593Smuzhiyun 	const char		*name;
210*4882a593Smuzhiyun 	struct dsa_port		*cpu_dp;
211*4882a593Smuzhiyun 	const char		*mac;
212*4882a593Smuzhiyun 	struct device_node	*dn;
213*4882a593Smuzhiyun 	unsigned int		ageing_time;
214*4882a593Smuzhiyun 	bool			vlan_filtering;
215*4882a593Smuzhiyun 	u8			stp_state;
216*4882a593Smuzhiyun 	struct net_device	*bridge_dev;
217*4882a593Smuzhiyun 	struct devlink_port	devlink_port;
218*4882a593Smuzhiyun 	bool			devlink_port_setup;
219*4882a593Smuzhiyun 	struct phylink		*pl;
220*4882a593Smuzhiyun 	struct phylink_config	pl_config;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	struct list_head list;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	/*
225*4882a593Smuzhiyun 	 * Give the switch driver somewhere to hang its per-port private data
226*4882a593Smuzhiyun 	 * structures (accessible from the tagger).
227*4882a593Smuzhiyun 	 */
228*4882a593Smuzhiyun 	void *priv;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	/*
231*4882a593Smuzhiyun 	 * Original copy of the master netdev ethtool_ops
232*4882a593Smuzhiyun 	 */
233*4882a593Smuzhiyun 	const struct ethtool_ops *orig_ethtool_ops;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	/*
236*4882a593Smuzhiyun 	 * Original copy of the master netdev net_device_ops
237*4882a593Smuzhiyun 	 */
238*4882a593Smuzhiyun 	const struct dsa_netdevice_ops *netdev_ops;
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	bool setup;
241*4882a593Smuzhiyun };
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun /* TODO: ideally DSA ports would have a single dp->link_dp member,
244*4882a593Smuzhiyun  * and no dst->rtable nor this struct dsa_link would be needed,
245*4882a593Smuzhiyun  * but this would require some more complex tree walking,
246*4882a593Smuzhiyun  * so keep it stupid at the moment and list them all.
247*4882a593Smuzhiyun  */
248*4882a593Smuzhiyun struct dsa_link {
249*4882a593Smuzhiyun 	struct dsa_port *dp;
250*4882a593Smuzhiyun 	struct dsa_port *link_dp;
251*4882a593Smuzhiyun 	struct list_head list;
252*4882a593Smuzhiyun };
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun struct dsa_switch {
255*4882a593Smuzhiyun 	bool setup;
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	struct device *dev;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	/*
260*4882a593Smuzhiyun 	 * Parent switch tree, and switch index.
261*4882a593Smuzhiyun 	 */
262*4882a593Smuzhiyun 	struct dsa_switch_tree	*dst;
263*4882a593Smuzhiyun 	unsigned int		index;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	/* Listener for switch fabric events */
266*4882a593Smuzhiyun 	struct notifier_block	nb;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	/*
269*4882a593Smuzhiyun 	 * Give the switch driver somewhere to hang its private data
270*4882a593Smuzhiyun 	 * structure.
271*4882a593Smuzhiyun 	 */
272*4882a593Smuzhiyun 	void *priv;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	/*
275*4882a593Smuzhiyun 	 * Configuration data for this switch.
276*4882a593Smuzhiyun 	 */
277*4882a593Smuzhiyun 	struct dsa_chip_data	*cd;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	/*
280*4882a593Smuzhiyun 	 * The switch operations.
281*4882a593Smuzhiyun 	 */
282*4882a593Smuzhiyun 	const struct dsa_switch_ops	*ops;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	/*
285*4882a593Smuzhiyun 	 * Slave mii_bus and devices for the individual ports.
286*4882a593Smuzhiyun 	 */
287*4882a593Smuzhiyun 	u32			phys_mii_mask;
288*4882a593Smuzhiyun 	struct mii_bus		*slave_mii_bus;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	/* Ageing Time limits in msecs */
291*4882a593Smuzhiyun 	unsigned int ageing_time_min;
292*4882a593Smuzhiyun 	unsigned int ageing_time_max;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	/* devlink used to represent this switch device */
295*4882a593Smuzhiyun 	struct devlink		*devlink;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	/* Number of switch port queues */
298*4882a593Smuzhiyun 	unsigned int		num_tx_queues;
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	/* Disallow bridge core from requesting different VLAN awareness
301*4882a593Smuzhiyun 	 * settings on ports if not hardware-supported
302*4882a593Smuzhiyun 	 */
303*4882a593Smuzhiyun 	bool			vlan_filtering_is_global;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	/* Pass .port_vlan_add and .port_vlan_del to drivers even for bridges
306*4882a593Smuzhiyun 	 * that have vlan_filtering=0. All drivers should ideally set this (and
307*4882a593Smuzhiyun 	 * then the option would get removed), but it is unknown whether this
308*4882a593Smuzhiyun 	 * would break things or not.
309*4882a593Smuzhiyun 	 */
310*4882a593Smuzhiyun 	bool			configure_vlan_while_not_filtering;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	/* If the switch driver always programs the CPU port as egress tagged
313*4882a593Smuzhiyun 	 * despite the VLAN configuration indicating otherwise, then setting
314*4882a593Smuzhiyun 	 * @untag_bridge_pvid will force the DSA receive path to pop the bridge's
315*4882a593Smuzhiyun 	 * default_pvid VLAN tagged frames to offer a consistent behavior
316*4882a593Smuzhiyun 	 * between a vlan_filtering=0 and vlan_filtering=1 bridge device.
317*4882a593Smuzhiyun 	 */
318*4882a593Smuzhiyun 	bool			untag_bridge_pvid;
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	/* In case vlan_filtering_is_global is set, the VLAN awareness state
321*4882a593Smuzhiyun 	 * should be retrieved from here and not from the per-port settings.
322*4882a593Smuzhiyun 	 */
323*4882a593Smuzhiyun 	bool			vlan_filtering;
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	/* MAC PCS does not provide link state change interrupt, and requires
326*4882a593Smuzhiyun 	 * polling. Flag passed on to PHYLINK.
327*4882a593Smuzhiyun 	 */
328*4882a593Smuzhiyun 	bool			pcs_poll;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	/* For switches that only have the MRU configurable. To ensure the
331*4882a593Smuzhiyun 	 * configured MTU is not exceeded, normalization of MRU on all bridged
332*4882a593Smuzhiyun 	 * interfaces is needed.
333*4882a593Smuzhiyun 	 */
334*4882a593Smuzhiyun 	bool			mtu_enforcement_ingress;
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	size_t num_ports;
337*4882a593Smuzhiyun };
338*4882a593Smuzhiyun 
dsa_to_port(struct dsa_switch * ds,int p)339*4882a593Smuzhiyun static inline struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p)
340*4882a593Smuzhiyun {
341*4882a593Smuzhiyun 	struct dsa_switch_tree *dst = ds->dst;
342*4882a593Smuzhiyun 	struct dsa_port *dp;
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	list_for_each_entry(dp, &dst->ports, list)
345*4882a593Smuzhiyun 		if (dp->ds == ds && dp->index == p)
346*4882a593Smuzhiyun 			return dp;
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	return NULL;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun 
dsa_is_unused_port(struct dsa_switch * ds,int p)351*4882a593Smuzhiyun static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p)
352*4882a593Smuzhiyun {
353*4882a593Smuzhiyun 	return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun 
dsa_is_cpu_port(struct dsa_switch * ds,int p)356*4882a593Smuzhiyun static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun 	return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_CPU;
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun 
dsa_is_dsa_port(struct dsa_switch * ds,int p)361*4882a593Smuzhiyun static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p)
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun 	return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_DSA;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun 
dsa_is_user_port(struct dsa_switch * ds,int p)366*4882a593Smuzhiyun static inline bool dsa_is_user_port(struct dsa_switch *ds, int p)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun 	return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_USER;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun 
dsa_user_ports(struct dsa_switch * ds)371*4882a593Smuzhiyun static inline u32 dsa_user_ports(struct dsa_switch *ds)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	u32 mask = 0;
374*4882a593Smuzhiyun 	int p;
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	for (p = 0; p < ds->num_ports; p++)
377*4882a593Smuzhiyun 		if (dsa_is_user_port(ds, p))
378*4882a593Smuzhiyun 			mask |= BIT(p);
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	return mask;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun /* Return the local port used to reach an arbitrary switch device */
dsa_routing_port(struct dsa_switch * ds,int device)384*4882a593Smuzhiyun static inline unsigned int dsa_routing_port(struct dsa_switch *ds, int device)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun 	struct dsa_switch_tree *dst = ds->dst;
387*4882a593Smuzhiyun 	struct dsa_link *dl;
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	list_for_each_entry(dl, &dst->rtable, list)
390*4882a593Smuzhiyun 		if (dl->dp->ds == ds && dl->link_dp->ds->index == device)
391*4882a593Smuzhiyun 			return dl->dp->index;
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	return ds->num_ports;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun /* Return the local port used to reach an arbitrary switch port */
dsa_towards_port(struct dsa_switch * ds,int device,int port)397*4882a593Smuzhiyun static inline unsigned int dsa_towards_port(struct dsa_switch *ds, int device,
398*4882a593Smuzhiyun 					    int port)
399*4882a593Smuzhiyun {
400*4882a593Smuzhiyun 	if (device == ds->index)
401*4882a593Smuzhiyun 		return port;
402*4882a593Smuzhiyun 	else
403*4882a593Smuzhiyun 		return dsa_routing_port(ds, device);
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun /* Return the local port used to reach the dedicated CPU port */
dsa_upstream_port(struct dsa_switch * ds,int port)407*4882a593Smuzhiyun static inline unsigned int dsa_upstream_port(struct dsa_switch *ds, int port)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun 	const struct dsa_port *dp = dsa_to_port(ds, port);
410*4882a593Smuzhiyun 	const struct dsa_port *cpu_dp = dp->cpu_dp;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	if (!cpu_dp)
413*4882a593Smuzhiyun 		return port;
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun 	return dsa_towards_port(ds, cpu_dp->ds->index, cpu_dp->index);
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun 
dsa_port_is_vlan_filtering(const struct dsa_port * dp)418*4882a593Smuzhiyun static inline bool dsa_port_is_vlan_filtering(const struct dsa_port *dp)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun 	const struct dsa_switch *ds = dp->ds;
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	if (ds->vlan_filtering_is_global)
423*4882a593Smuzhiyun 		return ds->vlan_filtering;
424*4882a593Smuzhiyun 	else
425*4882a593Smuzhiyun 		return dp->vlan_filtering;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,
429*4882a593Smuzhiyun 			      bool is_static, void *data);
430*4882a593Smuzhiyun struct dsa_switch_ops {
431*4882a593Smuzhiyun 	enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds,
432*4882a593Smuzhiyun 						  int port,
433*4882a593Smuzhiyun 						  enum dsa_tag_protocol mprot);
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	int	(*setup)(struct dsa_switch *ds);
436*4882a593Smuzhiyun 	void	(*teardown)(struct dsa_switch *ds);
437*4882a593Smuzhiyun 	u32	(*get_phy_flags)(struct dsa_switch *ds, int port);
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	/*
440*4882a593Smuzhiyun 	 * Access to the switch's PHY registers.
441*4882a593Smuzhiyun 	 */
442*4882a593Smuzhiyun 	int	(*phy_read)(struct dsa_switch *ds, int port, int regnum);
443*4882a593Smuzhiyun 	int	(*phy_write)(struct dsa_switch *ds, int port,
444*4882a593Smuzhiyun 			     int regnum, u16 val);
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	/*
447*4882a593Smuzhiyun 	 * Link state adjustment (called from libphy)
448*4882a593Smuzhiyun 	 */
449*4882a593Smuzhiyun 	void	(*adjust_link)(struct dsa_switch *ds, int port,
450*4882a593Smuzhiyun 				struct phy_device *phydev);
451*4882a593Smuzhiyun 	void	(*fixed_link_update)(struct dsa_switch *ds, int port,
452*4882a593Smuzhiyun 				struct fixed_phy_status *st);
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	/*
455*4882a593Smuzhiyun 	 * PHYLINK integration
456*4882a593Smuzhiyun 	 */
457*4882a593Smuzhiyun 	void	(*phylink_validate)(struct dsa_switch *ds, int port,
458*4882a593Smuzhiyun 				    unsigned long *supported,
459*4882a593Smuzhiyun 				    struct phylink_link_state *state);
460*4882a593Smuzhiyun 	int	(*phylink_mac_link_state)(struct dsa_switch *ds, int port,
461*4882a593Smuzhiyun 					  struct phylink_link_state *state);
462*4882a593Smuzhiyun 	void	(*phylink_mac_config)(struct dsa_switch *ds, int port,
463*4882a593Smuzhiyun 				      unsigned int mode,
464*4882a593Smuzhiyun 				      const struct phylink_link_state *state);
465*4882a593Smuzhiyun 	void	(*phylink_mac_an_restart)(struct dsa_switch *ds, int port);
466*4882a593Smuzhiyun 	void	(*phylink_mac_link_down)(struct dsa_switch *ds, int port,
467*4882a593Smuzhiyun 					 unsigned int mode,
468*4882a593Smuzhiyun 					 phy_interface_t interface);
469*4882a593Smuzhiyun 	void	(*phylink_mac_link_up)(struct dsa_switch *ds, int port,
470*4882a593Smuzhiyun 				       unsigned int mode,
471*4882a593Smuzhiyun 				       phy_interface_t interface,
472*4882a593Smuzhiyun 				       struct phy_device *phydev,
473*4882a593Smuzhiyun 				       int speed, int duplex,
474*4882a593Smuzhiyun 				       bool tx_pause, bool rx_pause);
475*4882a593Smuzhiyun 	void	(*phylink_fixed_state)(struct dsa_switch *ds, int port,
476*4882a593Smuzhiyun 				       struct phylink_link_state *state);
477*4882a593Smuzhiyun 	/*
478*4882a593Smuzhiyun 	 * ethtool hardware statistics.
479*4882a593Smuzhiyun 	 */
480*4882a593Smuzhiyun 	void	(*get_strings)(struct dsa_switch *ds, int port,
481*4882a593Smuzhiyun 			       u32 stringset, uint8_t *data);
482*4882a593Smuzhiyun 	void	(*get_ethtool_stats)(struct dsa_switch *ds,
483*4882a593Smuzhiyun 				     int port, uint64_t *data);
484*4882a593Smuzhiyun 	int	(*get_sset_count)(struct dsa_switch *ds, int port, int sset);
485*4882a593Smuzhiyun 	void	(*get_ethtool_phy_stats)(struct dsa_switch *ds,
486*4882a593Smuzhiyun 					 int port, uint64_t *data);
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	/*
489*4882a593Smuzhiyun 	 * ethtool Wake-on-LAN
490*4882a593Smuzhiyun 	 */
491*4882a593Smuzhiyun 	void	(*get_wol)(struct dsa_switch *ds, int port,
492*4882a593Smuzhiyun 			   struct ethtool_wolinfo *w);
493*4882a593Smuzhiyun 	int	(*set_wol)(struct dsa_switch *ds, int port,
494*4882a593Smuzhiyun 			   struct ethtool_wolinfo *w);
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	/*
497*4882a593Smuzhiyun 	 * ethtool timestamp info
498*4882a593Smuzhiyun 	 */
499*4882a593Smuzhiyun 	int	(*get_ts_info)(struct dsa_switch *ds, int port,
500*4882a593Smuzhiyun 			       struct ethtool_ts_info *ts);
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	/*
503*4882a593Smuzhiyun 	 * Suspend and resume
504*4882a593Smuzhiyun 	 */
505*4882a593Smuzhiyun 	int	(*suspend)(struct dsa_switch *ds);
506*4882a593Smuzhiyun 	int	(*resume)(struct dsa_switch *ds);
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	/*
509*4882a593Smuzhiyun 	 * Port enable/disable
510*4882a593Smuzhiyun 	 */
511*4882a593Smuzhiyun 	int	(*port_enable)(struct dsa_switch *ds, int port,
512*4882a593Smuzhiyun 			       struct phy_device *phy);
513*4882a593Smuzhiyun 	void	(*port_disable)(struct dsa_switch *ds, int port);
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	/*
516*4882a593Smuzhiyun 	 * Port's MAC EEE settings
517*4882a593Smuzhiyun 	 */
518*4882a593Smuzhiyun 	int	(*set_mac_eee)(struct dsa_switch *ds, int port,
519*4882a593Smuzhiyun 			       struct ethtool_eee *e);
520*4882a593Smuzhiyun 	int	(*get_mac_eee)(struct dsa_switch *ds, int port,
521*4882a593Smuzhiyun 			       struct ethtool_eee *e);
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	/* EEPROM access */
524*4882a593Smuzhiyun 	int	(*get_eeprom_len)(struct dsa_switch *ds);
525*4882a593Smuzhiyun 	int	(*get_eeprom)(struct dsa_switch *ds,
526*4882a593Smuzhiyun 			      struct ethtool_eeprom *eeprom, u8 *data);
527*4882a593Smuzhiyun 	int	(*set_eeprom)(struct dsa_switch *ds,
528*4882a593Smuzhiyun 			      struct ethtool_eeprom *eeprom, u8 *data);
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	/*
531*4882a593Smuzhiyun 	 * Register access.
532*4882a593Smuzhiyun 	 */
533*4882a593Smuzhiyun 	int	(*get_regs_len)(struct dsa_switch *ds, int port);
534*4882a593Smuzhiyun 	void	(*get_regs)(struct dsa_switch *ds, int port,
535*4882a593Smuzhiyun 			    struct ethtool_regs *regs, void *p);
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	/*
538*4882a593Smuzhiyun 	 * Bridge integration
539*4882a593Smuzhiyun 	 */
540*4882a593Smuzhiyun 	int	(*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
541*4882a593Smuzhiyun 	int	(*port_bridge_join)(struct dsa_switch *ds, int port,
542*4882a593Smuzhiyun 				    struct net_device *bridge);
543*4882a593Smuzhiyun 	void	(*port_bridge_leave)(struct dsa_switch *ds, int port,
544*4882a593Smuzhiyun 				     struct net_device *bridge);
545*4882a593Smuzhiyun 	void	(*port_stp_state_set)(struct dsa_switch *ds, int port,
546*4882a593Smuzhiyun 				      u8 state);
547*4882a593Smuzhiyun 	void	(*port_fast_age)(struct dsa_switch *ds, int port);
548*4882a593Smuzhiyun 	int	(*port_egress_floods)(struct dsa_switch *ds, int port,
549*4882a593Smuzhiyun 				      bool unicast, bool multicast);
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	/*
552*4882a593Smuzhiyun 	 * VLAN support
553*4882a593Smuzhiyun 	 */
554*4882a593Smuzhiyun 	int	(*port_vlan_filtering)(struct dsa_switch *ds, int port,
555*4882a593Smuzhiyun 				       bool vlan_filtering,
556*4882a593Smuzhiyun 				       struct switchdev_trans *trans);
557*4882a593Smuzhiyun 	int (*port_vlan_prepare)(struct dsa_switch *ds, int port,
558*4882a593Smuzhiyun 				 const struct switchdev_obj_port_vlan *vlan);
559*4882a593Smuzhiyun 	void (*port_vlan_add)(struct dsa_switch *ds, int port,
560*4882a593Smuzhiyun 			      const struct switchdev_obj_port_vlan *vlan);
561*4882a593Smuzhiyun 	int	(*port_vlan_del)(struct dsa_switch *ds, int port,
562*4882a593Smuzhiyun 				 const struct switchdev_obj_port_vlan *vlan);
563*4882a593Smuzhiyun 	/*
564*4882a593Smuzhiyun 	 * Forwarding database
565*4882a593Smuzhiyun 	 */
566*4882a593Smuzhiyun 	int	(*port_fdb_add)(struct dsa_switch *ds, int port,
567*4882a593Smuzhiyun 				const unsigned char *addr, u16 vid);
568*4882a593Smuzhiyun 	int	(*port_fdb_del)(struct dsa_switch *ds, int port,
569*4882a593Smuzhiyun 				const unsigned char *addr, u16 vid);
570*4882a593Smuzhiyun 	int	(*port_fdb_dump)(struct dsa_switch *ds, int port,
571*4882a593Smuzhiyun 				 dsa_fdb_dump_cb_t *cb, void *data);
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	/*
574*4882a593Smuzhiyun 	 * Multicast database
575*4882a593Smuzhiyun 	 */
576*4882a593Smuzhiyun 	int (*port_mdb_prepare)(struct dsa_switch *ds, int port,
577*4882a593Smuzhiyun 				const struct switchdev_obj_port_mdb *mdb);
578*4882a593Smuzhiyun 	void (*port_mdb_add)(struct dsa_switch *ds, int port,
579*4882a593Smuzhiyun 			     const struct switchdev_obj_port_mdb *mdb);
580*4882a593Smuzhiyun 	int	(*port_mdb_del)(struct dsa_switch *ds, int port,
581*4882a593Smuzhiyun 				const struct switchdev_obj_port_mdb *mdb);
582*4882a593Smuzhiyun 	/*
583*4882a593Smuzhiyun 	 * RXNFC
584*4882a593Smuzhiyun 	 */
585*4882a593Smuzhiyun 	int	(*get_rxnfc)(struct dsa_switch *ds, int port,
586*4882a593Smuzhiyun 			     struct ethtool_rxnfc *nfc, u32 *rule_locs);
587*4882a593Smuzhiyun 	int	(*set_rxnfc)(struct dsa_switch *ds, int port,
588*4882a593Smuzhiyun 			     struct ethtool_rxnfc *nfc);
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	/*
591*4882a593Smuzhiyun 	 * TC integration
592*4882a593Smuzhiyun 	 */
593*4882a593Smuzhiyun 	int	(*cls_flower_add)(struct dsa_switch *ds, int port,
594*4882a593Smuzhiyun 				  struct flow_cls_offload *cls, bool ingress);
595*4882a593Smuzhiyun 	int	(*cls_flower_del)(struct dsa_switch *ds, int port,
596*4882a593Smuzhiyun 				  struct flow_cls_offload *cls, bool ingress);
597*4882a593Smuzhiyun 	int	(*cls_flower_stats)(struct dsa_switch *ds, int port,
598*4882a593Smuzhiyun 				    struct flow_cls_offload *cls, bool ingress);
599*4882a593Smuzhiyun 	int	(*port_mirror_add)(struct dsa_switch *ds, int port,
600*4882a593Smuzhiyun 				   struct dsa_mall_mirror_tc_entry *mirror,
601*4882a593Smuzhiyun 				   bool ingress);
602*4882a593Smuzhiyun 	void	(*port_mirror_del)(struct dsa_switch *ds, int port,
603*4882a593Smuzhiyun 				   struct dsa_mall_mirror_tc_entry *mirror);
604*4882a593Smuzhiyun 	int	(*port_policer_add)(struct dsa_switch *ds, int port,
605*4882a593Smuzhiyun 				    struct dsa_mall_policer_tc_entry *policer);
606*4882a593Smuzhiyun 	void	(*port_policer_del)(struct dsa_switch *ds, int port);
607*4882a593Smuzhiyun 	int	(*port_setup_tc)(struct dsa_switch *ds, int port,
608*4882a593Smuzhiyun 				 enum tc_setup_type type, void *type_data);
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	/*
611*4882a593Smuzhiyun 	 * Cross-chip operations
612*4882a593Smuzhiyun 	 */
613*4882a593Smuzhiyun 	int	(*crosschip_bridge_join)(struct dsa_switch *ds, int tree_index,
614*4882a593Smuzhiyun 					 int sw_index, int port,
615*4882a593Smuzhiyun 					 struct net_device *br);
616*4882a593Smuzhiyun 	void	(*crosschip_bridge_leave)(struct dsa_switch *ds, int tree_index,
617*4882a593Smuzhiyun 					  int sw_index, int port,
618*4882a593Smuzhiyun 					  struct net_device *br);
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun 	/*
621*4882a593Smuzhiyun 	 * PTP functionality
622*4882a593Smuzhiyun 	 */
623*4882a593Smuzhiyun 	int	(*port_hwtstamp_get)(struct dsa_switch *ds, int port,
624*4882a593Smuzhiyun 				     struct ifreq *ifr);
625*4882a593Smuzhiyun 	int	(*port_hwtstamp_set)(struct dsa_switch *ds, int port,
626*4882a593Smuzhiyun 				     struct ifreq *ifr);
627*4882a593Smuzhiyun 	bool	(*port_txtstamp)(struct dsa_switch *ds, int port,
628*4882a593Smuzhiyun 				 struct sk_buff *clone, unsigned int type);
629*4882a593Smuzhiyun 	bool	(*port_rxtstamp)(struct dsa_switch *ds, int port,
630*4882a593Smuzhiyun 				 struct sk_buff *skb, unsigned int type);
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	/* Devlink parameters, etc */
633*4882a593Smuzhiyun 	int	(*devlink_param_get)(struct dsa_switch *ds, u32 id,
634*4882a593Smuzhiyun 				     struct devlink_param_gset_ctx *ctx);
635*4882a593Smuzhiyun 	int	(*devlink_param_set)(struct dsa_switch *ds, u32 id,
636*4882a593Smuzhiyun 				     struct devlink_param_gset_ctx *ctx);
637*4882a593Smuzhiyun 	int	(*devlink_info_get)(struct dsa_switch *ds,
638*4882a593Smuzhiyun 				    struct devlink_info_req *req,
639*4882a593Smuzhiyun 				    struct netlink_ext_ack *extack);
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 	/*
642*4882a593Smuzhiyun 	 * MTU change functionality. Switches can also adjust their MRU through
643*4882a593Smuzhiyun 	 * this method. By MTU, one understands the SDU (L2 payload) length.
644*4882a593Smuzhiyun 	 * If the switch needs to account for the DSA tag on the CPU port, this
645*4882a593Smuzhiyun 	 * method needs to do so privately.
646*4882a593Smuzhiyun 	 */
647*4882a593Smuzhiyun 	int	(*port_change_mtu)(struct dsa_switch *ds, int port,
648*4882a593Smuzhiyun 				   int new_mtu);
649*4882a593Smuzhiyun 	int	(*port_max_mtu)(struct dsa_switch *ds, int port);
650*4882a593Smuzhiyun };
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes)		\
653*4882a593Smuzhiyun 	DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes,		\
654*4882a593Smuzhiyun 			     dsa_devlink_param_get, dsa_devlink_param_set, NULL)
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun int dsa_devlink_param_get(struct devlink *dl, u32 id,
657*4882a593Smuzhiyun 			  struct devlink_param_gset_ctx *ctx);
658*4882a593Smuzhiyun int dsa_devlink_param_set(struct devlink *dl, u32 id,
659*4882a593Smuzhiyun 			  struct devlink_param_gset_ctx *ctx);
660*4882a593Smuzhiyun int dsa_devlink_params_register(struct dsa_switch *ds,
661*4882a593Smuzhiyun 				const struct devlink_param *params,
662*4882a593Smuzhiyun 				size_t params_count);
663*4882a593Smuzhiyun void dsa_devlink_params_unregister(struct dsa_switch *ds,
664*4882a593Smuzhiyun 				   const struct devlink_param *params,
665*4882a593Smuzhiyun 				   size_t params_count);
666*4882a593Smuzhiyun int dsa_devlink_resource_register(struct dsa_switch *ds,
667*4882a593Smuzhiyun 				  const char *resource_name,
668*4882a593Smuzhiyun 				  u64 resource_size,
669*4882a593Smuzhiyun 				  u64 resource_id,
670*4882a593Smuzhiyun 				  u64 parent_resource_id,
671*4882a593Smuzhiyun 				  const struct devlink_resource_size_params *size_params);
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun void dsa_devlink_resources_unregister(struct dsa_switch *ds);
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun void dsa_devlink_resource_occ_get_register(struct dsa_switch *ds,
676*4882a593Smuzhiyun 					   u64 resource_id,
677*4882a593Smuzhiyun 					   devlink_resource_occ_get_t *occ_get,
678*4882a593Smuzhiyun 					   void *occ_get_priv);
679*4882a593Smuzhiyun void dsa_devlink_resource_occ_get_unregister(struct dsa_switch *ds,
680*4882a593Smuzhiyun 					     u64 resource_id);
681*4882a593Smuzhiyun struct devlink_region *
682*4882a593Smuzhiyun dsa_devlink_region_create(struct dsa_switch *ds,
683*4882a593Smuzhiyun 			  const struct devlink_region_ops *ops,
684*4882a593Smuzhiyun 			  u32 region_max_snapshots, u64 region_size);
685*4882a593Smuzhiyun struct devlink_region *
686*4882a593Smuzhiyun dsa_devlink_port_region_create(struct dsa_switch *ds,
687*4882a593Smuzhiyun 			       int port,
688*4882a593Smuzhiyun 			       const struct devlink_port_region_ops *ops,
689*4882a593Smuzhiyun 			       u32 region_max_snapshots, u64 region_size);
690*4882a593Smuzhiyun void dsa_devlink_region_destroy(struct devlink_region *region);
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun struct dsa_port *dsa_port_from_netdev(struct net_device *netdev);
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun struct dsa_devlink_priv {
695*4882a593Smuzhiyun 	struct dsa_switch *ds;
696*4882a593Smuzhiyun };
697*4882a593Smuzhiyun 
dsa_devlink_to_ds(struct devlink * dl)698*4882a593Smuzhiyun static inline struct dsa_switch *dsa_devlink_to_ds(struct devlink *dl)
699*4882a593Smuzhiyun {
700*4882a593Smuzhiyun 	struct dsa_devlink_priv *dl_priv = devlink_priv(dl);
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	return dl_priv->ds;
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun static inline
dsa_devlink_port_to_ds(struct devlink_port * port)706*4882a593Smuzhiyun struct dsa_switch *dsa_devlink_port_to_ds(struct devlink_port *port)
707*4882a593Smuzhiyun {
708*4882a593Smuzhiyun 	struct devlink *dl = port->devlink;
709*4882a593Smuzhiyun 	struct dsa_devlink_priv *dl_priv = devlink_priv(dl);
710*4882a593Smuzhiyun 
711*4882a593Smuzhiyun 	return dl_priv->ds;
712*4882a593Smuzhiyun }
713*4882a593Smuzhiyun 
dsa_devlink_port_to_port(struct devlink_port * port)714*4882a593Smuzhiyun static inline int dsa_devlink_port_to_port(struct devlink_port *port)
715*4882a593Smuzhiyun {
716*4882a593Smuzhiyun 	return port->index;
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun struct dsa_switch_driver {
720*4882a593Smuzhiyun 	struct list_head	list;
721*4882a593Smuzhiyun 	const struct dsa_switch_ops *ops;
722*4882a593Smuzhiyun };
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun struct net_device *dsa_dev_to_net_device(struct device *dev);
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun /* Keep inline for faster access in hot path */
netdev_uses_dsa(const struct net_device * dev)727*4882a593Smuzhiyun static inline bool netdev_uses_dsa(const struct net_device *dev)
728*4882a593Smuzhiyun {
729*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_NET_DSA)
730*4882a593Smuzhiyun 	return dev->dsa_ptr && dev->dsa_ptr->rcv;
731*4882a593Smuzhiyun #endif
732*4882a593Smuzhiyun 	return false;
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun 
dsa_can_decode(const struct sk_buff * skb,struct net_device * dev)735*4882a593Smuzhiyun static inline bool dsa_can_decode(const struct sk_buff *skb,
736*4882a593Smuzhiyun 				  struct net_device *dev)
737*4882a593Smuzhiyun {
738*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_NET_DSA)
739*4882a593Smuzhiyun 	return !dev->dsa_ptr->filter || dev->dsa_ptr->filter(skb, dev);
740*4882a593Smuzhiyun #endif
741*4882a593Smuzhiyun 	return false;
742*4882a593Smuzhiyun }
743*4882a593Smuzhiyun 
744*4882a593Smuzhiyun /* All DSA tags that push the EtherType to the right (basically all except tail
745*4882a593Smuzhiyun  * tags, which don't break dissection) can be treated the same from the
746*4882a593Smuzhiyun  * perspective of the flow dissector.
747*4882a593Smuzhiyun  *
748*4882a593Smuzhiyun  * We need to return:
749*4882a593Smuzhiyun  *  - offset: the (B - A) difference between:
750*4882a593Smuzhiyun  *    A. the position of the real EtherType and
751*4882a593Smuzhiyun  *    B. the current skb->data (aka ETH_HLEN bytes into the frame, aka 2 bytes
752*4882a593Smuzhiyun  *       after the normal EtherType was supposed to be)
753*4882a593Smuzhiyun  *    The offset in bytes is exactly equal to the tagger overhead (and half of
754*4882a593Smuzhiyun  *    that, in __be16 shorts).
755*4882a593Smuzhiyun  *
756*4882a593Smuzhiyun  *  - proto: the value of the real EtherType.
757*4882a593Smuzhiyun  */
dsa_tag_generic_flow_dissect(const struct sk_buff * skb,__be16 * proto,int * offset)758*4882a593Smuzhiyun static inline void dsa_tag_generic_flow_dissect(const struct sk_buff *skb,
759*4882a593Smuzhiyun 						__be16 *proto, int *offset)
760*4882a593Smuzhiyun {
761*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_NET_DSA)
762*4882a593Smuzhiyun 	const struct dsa_device_ops *ops = skb->dev->dsa_ptr->tag_ops;
763*4882a593Smuzhiyun 	int tag_len = ops->overhead;
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 	*offset = tag_len;
766*4882a593Smuzhiyun 	*proto = ((__be16 *)skb->data)[(tag_len / 2) - 1];
767*4882a593Smuzhiyun #endif
768*4882a593Smuzhiyun }
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_NET_DSA)
__dsa_netdevice_ops_check(struct net_device * dev)771*4882a593Smuzhiyun static inline int __dsa_netdevice_ops_check(struct net_device *dev)
772*4882a593Smuzhiyun {
773*4882a593Smuzhiyun 	int err = -EOPNOTSUPP;
774*4882a593Smuzhiyun 
775*4882a593Smuzhiyun 	if (!dev->dsa_ptr)
776*4882a593Smuzhiyun 		return err;
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun 	if (!dev->dsa_ptr->netdev_ops)
779*4882a593Smuzhiyun 		return err;
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun 	return 0;
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun 
dsa_ndo_do_ioctl(struct net_device * dev,struct ifreq * ifr,int cmd)784*4882a593Smuzhiyun static inline int dsa_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr,
785*4882a593Smuzhiyun 				   int cmd)
786*4882a593Smuzhiyun {
787*4882a593Smuzhiyun 	const struct dsa_netdevice_ops *ops;
788*4882a593Smuzhiyun 	int err;
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun 	err = __dsa_netdevice_ops_check(dev);
791*4882a593Smuzhiyun 	if (err)
792*4882a593Smuzhiyun 		return err;
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 	ops = dev->dsa_ptr->netdev_ops;
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun 	return ops->ndo_do_ioctl(dev, ifr, cmd);
797*4882a593Smuzhiyun }
798*4882a593Smuzhiyun #else
dsa_ndo_do_ioctl(struct net_device * dev,struct ifreq * ifr,int cmd)799*4882a593Smuzhiyun static inline int dsa_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr,
800*4882a593Smuzhiyun 				   int cmd)
801*4882a593Smuzhiyun {
802*4882a593Smuzhiyun 	return -EOPNOTSUPP;
803*4882a593Smuzhiyun }
804*4882a593Smuzhiyun #endif
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun void dsa_unregister_switch(struct dsa_switch *ds);
807*4882a593Smuzhiyun int dsa_register_switch(struct dsa_switch *ds);
808*4882a593Smuzhiyun struct dsa_switch *dsa_switch_find(int tree_index, int sw_index);
809*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
810*4882a593Smuzhiyun int dsa_switch_suspend(struct dsa_switch *ds);
811*4882a593Smuzhiyun int dsa_switch_resume(struct dsa_switch *ds);
812*4882a593Smuzhiyun #else
dsa_switch_suspend(struct dsa_switch * ds)813*4882a593Smuzhiyun static inline int dsa_switch_suspend(struct dsa_switch *ds)
814*4882a593Smuzhiyun {
815*4882a593Smuzhiyun 	return 0;
816*4882a593Smuzhiyun }
dsa_switch_resume(struct dsa_switch * ds)817*4882a593Smuzhiyun static inline int dsa_switch_resume(struct dsa_switch *ds)
818*4882a593Smuzhiyun {
819*4882a593Smuzhiyun 	return 0;
820*4882a593Smuzhiyun }
821*4882a593Smuzhiyun #endif /* CONFIG_PM_SLEEP */
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun enum dsa_notifier_type {
824*4882a593Smuzhiyun 	DSA_PORT_REGISTER,
825*4882a593Smuzhiyun 	DSA_PORT_UNREGISTER,
826*4882a593Smuzhiyun };
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun struct dsa_notifier_info {
829*4882a593Smuzhiyun 	struct net_device *dev;
830*4882a593Smuzhiyun };
831*4882a593Smuzhiyun 
832*4882a593Smuzhiyun struct dsa_notifier_register_info {
833*4882a593Smuzhiyun 	struct dsa_notifier_info info;	/* must be first */
834*4882a593Smuzhiyun 	struct net_device *master;
835*4882a593Smuzhiyun 	unsigned int port_number;
836*4882a593Smuzhiyun 	unsigned int switch_number;
837*4882a593Smuzhiyun };
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun static inline struct net_device *
dsa_notifier_info_to_dev(const struct dsa_notifier_info * info)840*4882a593Smuzhiyun dsa_notifier_info_to_dev(const struct dsa_notifier_info *info)
841*4882a593Smuzhiyun {
842*4882a593Smuzhiyun 	return info->dev;
843*4882a593Smuzhiyun }
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_NET_DSA)
846*4882a593Smuzhiyun int register_dsa_notifier(struct notifier_block *nb);
847*4882a593Smuzhiyun int unregister_dsa_notifier(struct notifier_block *nb);
848*4882a593Smuzhiyun int call_dsa_notifiers(unsigned long val, struct net_device *dev,
849*4882a593Smuzhiyun 		       struct dsa_notifier_info *info);
850*4882a593Smuzhiyun #else
register_dsa_notifier(struct notifier_block * nb)851*4882a593Smuzhiyun static inline int register_dsa_notifier(struct notifier_block *nb)
852*4882a593Smuzhiyun {
853*4882a593Smuzhiyun 	return 0;
854*4882a593Smuzhiyun }
855*4882a593Smuzhiyun 
unregister_dsa_notifier(struct notifier_block * nb)856*4882a593Smuzhiyun static inline int unregister_dsa_notifier(struct notifier_block *nb)
857*4882a593Smuzhiyun {
858*4882a593Smuzhiyun 	return 0;
859*4882a593Smuzhiyun }
860*4882a593Smuzhiyun 
call_dsa_notifiers(unsigned long val,struct net_device * dev,struct dsa_notifier_info * info)861*4882a593Smuzhiyun static inline int call_dsa_notifiers(unsigned long val, struct net_device *dev,
862*4882a593Smuzhiyun 				     struct dsa_notifier_info *info)
863*4882a593Smuzhiyun {
864*4882a593Smuzhiyun 	return NOTIFY_DONE;
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun #endif
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun /* Broadcom tag specific helpers to insert and extract queue/port number */
869*4882a593Smuzhiyun #define BRCM_TAG_SET_PORT_QUEUE(p, q)	((p) << 8 | q)
870*4882a593Smuzhiyun #define BRCM_TAG_GET_PORT(v)		((v) >> 8)
871*4882a593Smuzhiyun #define BRCM_TAG_GET_QUEUE(v)		((v) & 0xff)
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun 
874*4882a593Smuzhiyun netdev_tx_t dsa_enqueue_skb(struct sk_buff *skb, struct net_device *dev);
875*4882a593Smuzhiyun int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data);
876*4882a593Smuzhiyun int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data);
877*4882a593Smuzhiyun int dsa_port_get_phy_sset_count(struct dsa_port *dp);
878*4882a593Smuzhiyun void dsa_port_phylink_mac_change(struct dsa_switch *ds, int port, bool up);
879*4882a593Smuzhiyun 
880*4882a593Smuzhiyun struct dsa_tag_driver {
881*4882a593Smuzhiyun 	const struct dsa_device_ops *ops;
882*4882a593Smuzhiyun 	struct list_head list;
883*4882a593Smuzhiyun 	struct module *owner;
884*4882a593Smuzhiyun };
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun void dsa_tag_drivers_register(struct dsa_tag_driver *dsa_tag_driver_array[],
887*4882a593Smuzhiyun 			      unsigned int count,
888*4882a593Smuzhiyun 			      struct module *owner);
889*4882a593Smuzhiyun void dsa_tag_drivers_unregister(struct dsa_tag_driver *dsa_tag_driver_array[],
890*4882a593Smuzhiyun 				unsigned int count);
891*4882a593Smuzhiyun 
892*4882a593Smuzhiyun #define dsa_tag_driver_module_drivers(__dsa_tag_drivers_array, __count)	\
893*4882a593Smuzhiyun static int __init dsa_tag_driver_module_init(void)			\
894*4882a593Smuzhiyun {									\
895*4882a593Smuzhiyun 	dsa_tag_drivers_register(__dsa_tag_drivers_array, __count,	\
896*4882a593Smuzhiyun 				 THIS_MODULE);				\
897*4882a593Smuzhiyun 	return 0;							\
898*4882a593Smuzhiyun }									\
899*4882a593Smuzhiyun module_init(dsa_tag_driver_module_init);				\
900*4882a593Smuzhiyun 									\
901*4882a593Smuzhiyun static void __exit dsa_tag_driver_module_exit(void)			\
902*4882a593Smuzhiyun {									\
903*4882a593Smuzhiyun 	dsa_tag_drivers_unregister(__dsa_tag_drivers_array, __count);	\
904*4882a593Smuzhiyun }									\
905*4882a593Smuzhiyun module_exit(dsa_tag_driver_module_exit)
906*4882a593Smuzhiyun 
907*4882a593Smuzhiyun /**
908*4882a593Smuzhiyun  * module_dsa_tag_drivers() - Helper macro for registering DSA tag
909*4882a593Smuzhiyun  * drivers
910*4882a593Smuzhiyun  * @__ops_array: Array of tag driver strucutres
911*4882a593Smuzhiyun  *
912*4882a593Smuzhiyun  * Helper macro for DSA tag drivers which do not do anything special
913*4882a593Smuzhiyun  * in module init/exit. Each module may only use this macro once, and
914*4882a593Smuzhiyun  * calling it replaces module_init() and module_exit().
915*4882a593Smuzhiyun  */
916*4882a593Smuzhiyun #define module_dsa_tag_drivers(__ops_array)				\
917*4882a593Smuzhiyun dsa_tag_driver_module_drivers(__ops_array, ARRAY_SIZE(__ops_array))
918*4882a593Smuzhiyun 
919*4882a593Smuzhiyun #define DSA_TAG_DRIVER_NAME(__ops) dsa_tag_driver ## _ ## __ops
920*4882a593Smuzhiyun 
921*4882a593Smuzhiyun /* Create a static structure we can build a linked list of dsa_tag
922*4882a593Smuzhiyun  * drivers
923*4882a593Smuzhiyun  */
924*4882a593Smuzhiyun #define DSA_TAG_DRIVER(__ops)						\
925*4882a593Smuzhiyun static struct dsa_tag_driver DSA_TAG_DRIVER_NAME(__ops) = {		\
926*4882a593Smuzhiyun 	.ops = &__ops,							\
927*4882a593Smuzhiyun }
928*4882a593Smuzhiyun 
929*4882a593Smuzhiyun /**
930*4882a593Smuzhiyun  * module_dsa_tag_driver() - Helper macro for registering a single DSA tag
931*4882a593Smuzhiyun  * driver
932*4882a593Smuzhiyun  * @__ops: Single tag driver structures
933*4882a593Smuzhiyun  *
934*4882a593Smuzhiyun  * Helper macro for DSA tag drivers which do not do anything special
935*4882a593Smuzhiyun  * in module init/exit. Each module may only use this macro once, and
936*4882a593Smuzhiyun  * calling it replaces module_init() and module_exit().
937*4882a593Smuzhiyun  */
938*4882a593Smuzhiyun #define module_dsa_tag_driver(__ops)					\
939*4882a593Smuzhiyun DSA_TAG_DRIVER(__ops);							\
940*4882a593Smuzhiyun 									\
941*4882a593Smuzhiyun static struct dsa_tag_driver *dsa_tag_driver_array[] =	{		\
942*4882a593Smuzhiyun 	&DSA_TAG_DRIVER_NAME(__ops)					\
943*4882a593Smuzhiyun };									\
944*4882a593Smuzhiyun module_dsa_tag_drivers(dsa_tag_driver_array)
945*4882a593Smuzhiyun #endif
946*4882a593Smuzhiyun 
947