Blame view

include/net/dsa.h 19.7 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  /* SPDX-License-Identifier: GPL-2.0-or-later */
91da11f87   Lennert Buytenhek   net: Distributed ...
2
3
  /*
   * include/net/dsa.h - Driver for Distributed Switch Architecture switch chips
e84665c9c   Lennert Buytenhek   dsa: add switch c...
4
   * Copyright (c) 2008-2009 Marvell Semiconductor
91da11f87   Lennert Buytenhek   net: Distributed ...
5
6
7
8
   */
  
  #ifndef __LINUX_NET_DSA_H
  #define __LINUX_NET_DSA_H
4d56a29f1   Russell King   net: dsa: remove ...
9
  #include <linux/if.h>
ea1f51bef   Axel Lin   dsa: Include linu...
10
  #include <linux/if_ether.h>
c8f0b8699   Ben Hutchings   dsa: Move all def...
11
  #include <linux/list.h>
f515f192a   Vivien Didelot   net: dsa: add swi...
12
  #include <linux/notifier.h>
cf50dcc24   Ben Hutchings   dsa: Change dsa_u...
13
14
  #include <linux/timer.h>
  #include <linux/workqueue.h>
fa981d9af   Florian Fainelli   net: dsa: provide...
15
  #include <linux/of.h>
a28205437   Florian Fainelli   net: dsa: add inc...
16
  #include <linux/ethtool.h>
0336369d3   Brandon Streiff   net: dsa: forward...
17
  #include <linux/net_tstamp.h>
11d8f3dda   Florian Fainelli   net: dsa: Add PHY...
18
  #include <linux/phy.h>
ecfc93721   Florian Fainelli   net: dsa: Split p...
19
  #include <linux/platform_data/dsa.h>
44cc27e43   Ioana Ciornei   net: phylink: Add...
20
  #include <linux/phylink.h>
96567d5da   Andrew Lunn   net: dsa: dsa2: A...
21
  #include <net/devlink.h>
f0c24ccf4   Vivien Didelot   net: dsa: include...
22
  #include <net/switchdev.h>
cf50dcc24   Ben Hutchings   dsa: Change dsa_u...
23

f50f21274   Florian Fainelli   net: dsa: Add plu...
24
  struct tc_action;
4d56a29f1   Russell King   net: dsa: remove ...
25
26
  struct phy_device;
  struct fixed_phy_status;
11d8f3dda   Florian Fainelli   net: dsa: Add PHY...
27
  struct phylink_link_state;
f50f21274   Florian Fainelli   net: dsa: Add plu...
28

0b42f0336   Andrew Lunn   dsa: Add MODULE_A...
29
30
31
32
33
34
35
36
37
38
39
40
  #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
f9bbe4477   Vladimir Oltean   net: dsa: Optiona...
41
  #define DSA_TAG_PROTO_8021Q_VALUE		12
227d07a07   Vladimir Oltean   net: dsa: sja1105...
42
  #define DSA_TAG_PROTO_SJA1105_VALUE		13
016e43a26   Tristram Ha   net: dsa: ksz: Ad...
43
  #define DSA_TAG_PROTO_KSZ8795_VALUE		14
ea238a2d6   Vladimir Oltean   net: dsa: ocelot:...
44
  #define DSA_TAG_PROTO_OCELOT_VALUE		15
0b42f0336   Andrew Lunn   dsa: Add MODULE_A...
45

ac7a04c33   Florian Fainelli   net: dsa: change ...
46
  enum dsa_tag_protocol {
0b42f0336   Andrew Lunn   dsa: Add MODULE_A...
47
48
49
50
51
52
53
54
55
56
57
58
  	DSA_TAG_PROTO_NONE		= DSA_TAG_PROTO_NONE_VALUE,
  	DSA_TAG_PROTO_BRCM		= DSA_TAG_PROTO_BRCM_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,
f9bbe4477   Vladimir Oltean   net: dsa: Optiona...
59
  	DSA_TAG_PROTO_8021Q		= DSA_TAG_PROTO_8021Q_VALUE,
227d07a07   Vladimir Oltean   net: dsa: sja1105...
60
  	DSA_TAG_PROTO_SJA1105		= DSA_TAG_PROTO_SJA1105_VALUE,
016e43a26   Tristram Ha   net: dsa: ksz: Ad...
61
  	DSA_TAG_PROTO_KSZ8795		= DSA_TAG_PROTO_KSZ8795_VALUE,
ea238a2d6   Vladimir Oltean   net: dsa: ocelot:...
62
  	DSA_TAG_PROTO_OCELOT		= DSA_TAG_PROTO_OCELOT_VALUE,
ac7a04c33   Florian Fainelli   net: dsa: change ...
63
  };
5037d532b   Florian Fainelli   net: dsa: add Bro...
64

5075314e4   Alexander Duyck   dsa: Split ops up...
65
  struct packet_type;
90af1059c   Brandon Streiff   net: dsa: forward...
66
  struct dsa_switch;
3e8a72d1d   Florian Fainelli   net: dsa: reduce ...
67

68277a2c9   John Crispin   net-next: dsa: mo...
68
69
70
  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,
89e49506b   Florian Westphal   dsa: remove unuse...
71
  			       struct packet_type *pt);
598a96801   John Crispin   net-next: dsa: ad...
72
73
  	int (*flow_dissect)(const struct sk_buff *skb, __be16 *proto,
  			    int *offset);
cc1939e4b   Vladimir Oltean   net: dsa: Allow d...
74
75
76
77
78
  	/* Used to determine which traffic should match the DSA filter in
  	 * eth_type_trans, and which, if any, should bypass it and be processed
  	 * as regular on the master net device.
  	 */
  	bool (*filter)(const struct sk_buff *skb, struct net_device *dev);
a5dd30877   Andrew Lunn   net: dsa: Add ove...
79
  	unsigned int overhead;
875138f81   Andrew Lunn   dsa: Move tagger ...
80
  	const char *name;
056eed2fb   Andrew Lunn   dsa: Add TAG prot...
81
  	enum dsa_tag_protocol proto;
68277a2c9   John Crispin   net-next: dsa: mo...
82
  };
0b42f0336   Andrew Lunn   dsa: Add MODULE_A...
83
84
85
  #define DSA_TAG_DRIVER_ALIAS "dsa_tag-"
  #define MODULE_ALIAS_DSA_TAG_DRIVER(__proto)				\
  	MODULE_ALIAS(DSA_TAG_DRIVER_ALIAS __stringify(__proto##_VALUE))
b68b0dd0f   Vladimir Oltean   net: dsa: Keep pr...
86
87
  struct dsa_skb_cb {
  	struct sk_buff *clone;
97a69a0de   Vladimir Oltean   net: dsa: Add sup...
88
  	bool deferred_xmit;
b68b0dd0f   Vladimir Oltean   net: dsa: Keep pr...
89
90
91
92
93
94
95
96
97
98
  };
  
  struct __dsa_skb_cb {
  	struct dsa_skb_cb cb;
  	u8 priv[48 - sizeof(struct dsa_skb_cb)];
  };
  
  #define __DSA_SKB_CB(skb) ((struct __dsa_skb_cb *)((skb)->cb))
  
  #define DSA_SKB_CB(skb) ((struct dsa_skb_cb *)((skb)->cb))
b68b0dd0f   Vladimir Oltean   net: dsa: Keep pr...
99
100
  #define DSA_SKB_CB_PRIV(skb)			\
  	((void *)(skb)->cb + offsetof(struct __dsa_skb_cb, priv))
cf50dcc24   Ben Hutchings   dsa: Change dsa_u...
101
  struct dsa_switch_tree {
83c0afaec   Andrew Lunn   net: dsa: Add new...
102
  	struct list_head	list;
f515f192a   Vivien Didelot   net: dsa: add swi...
103
104
  	/* Notifier chain for switch-wide events */
  	struct raw_notifier_head	nh;
83c0afaec   Andrew Lunn   net: dsa: Add new...
105
  	/* Tree identifier */
49463b7f2   Vivien Didelot   net: dsa: make tr...
106
  	unsigned int index;
83c0afaec   Andrew Lunn   net: dsa: Add new...
107
108
109
110
111
  
  	/* Number of switches attached to this tree */
  	struct kref refcount;
  
  	/* Has this tree been applied to the hardware? */
ec15dd426   Vivien Didelot   net: dsa: setup a...
112
  	bool setup;
83c0afaec   Andrew Lunn   net: dsa: Add new...
113

cf50dcc24   Ben Hutchings   dsa: Change dsa_u...
114
115
116
117
118
  	/*
  	 * Configuration data for the platform device that owns
  	 * this dsa switch tree instance.
  	 */
  	struct dsa_platform_data	*pd;
cf50dcc24   Ben Hutchings   dsa: Change dsa_u...
119
  	/*
8b0d3ea55   Vivien Didelot   net: dsa: store C...
120
  	 * The switch port to which the CPU is attached.
cf50dcc24   Ben Hutchings   dsa: Change dsa_u...
121
  	 */
8b0d3ea55   Vivien Didelot   net: dsa: store C...
122
  	struct dsa_port		*cpu_dp;
cf50dcc24   Ben Hutchings   dsa: Change dsa_u...
123
124
  
  	/*
cf50dcc24   Ben Hutchings   dsa: Change dsa_u...
125
126
127
128
  	 * Data for the individual switch chips.
  	 */
  	struct dsa_switch	*ds[DSA_MAX_SWITCHES];
  };
f50f21274   Florian Fainelli   net: dsa: Add plu...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  /* TC matchall action types, only mirroring for now */
  enum dsa_port_mall_action_type {
  	DSA_PORT_MALL_MIRROR,
  };
  
  /* 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;
  	};
  };
c8b098086   Andrew Lunn   net: dsa: Add a p...
149
  struct dsa_port {
f8b8b1cd5   Vivien Didelot   net: dsa: split d...
150
151
152
153
154
155
156
  	/* A CPU port is physically connected to a master device.
  	 * A user port exposed to userspace has a slave device.
  	 */
  	union {
  		struct net_device *master;
  		struct net_device *slave;
  	};
152402483   Vivien Didelot   net: dsa: add tag...
157
158
  	/* CPU port tagging operations used by master or slave devices */
  	const struct dsa_device_ops *tag_ops;
3e41f93b3   Vivien Didelot   net: dsa: prepare...
159
160
161
162
  	/* Copies for faster access in master receive hot path */
  	struct dsa_switch_tree *dst;
  	struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev,
  			       struct packet_type *pt);
cc1939e4b   Vladimir Oltean   net: dsa: Allow d...
163
  	bool (*filter)(const struct sk_buff *skb, struct net_device *dev);
3e41f93b3   Vivien Didelot   net: dsa: prepare...
164

057cad2c5   Vivien Didelot   net: dsa: define ...
165
166
167
168
169
170
  	enum {
  		DSA_PORT_TYPE_UNUSED = 0,
  		DSA_PORT_TYPE_CPU,
  		DSA_PORT_TYPE_DSA,
  		DSA_PORT_TYPE_USER,
  	} type;
818be8489   Vivien Didelot   net: dsa: add ds ...
171
172
  	struct dsa_switch	*ds;
  	unsigned int		index;
71e0bbde0   Florian Fainelli   net: dsa: Add sup...
173
  	const char		*name;
68b2d4a84   Vivien Didelot   net: dsa: make cp...
174
  	struct dsa_port		*cpu_dp;
a2c7023f7   Xiaofei Shen   net: dsa: read ma...
175
  	const char		*mac;
189b0d93e   Andrew Lunn   net: dsa: Move po...
176
  	struct device_node	*dn;
34a79f63b   Vivien Didelot   net: dsa: support...
177
  	unsigned int		ageing_time;
33162e9a0   Vladimir Oltean   net: dsa: Store v...
178
  	bool			vlan_filtering;
732f794c1   Vivien Didelot   net: dsa: add por...
179
  	u8			stp_state;
a5e9a02e1   Vivien Didelot   net: dsa: move br...
180
  	struct net_device	*bridge_dev;
96567d5da   Andrew Lunn   net: dsa: dsa2: A...
181
  	struct devlink_port	devlink_port;
aab9c4067   Florian Fainelli   net: dsa: Plug in...
182
  	struct phylink		*pl;
44cc27e43   Ioana Ciornei   net: phylink: Add...
183
  	struct phylink_config	pl_config;
97a69a0de   Vladimir Oltean   net: dsa: Add sup...
184
185
186
  
  	struct work_struct	xmit_work;
  	struct sk_buff_head	xmit_queue;
67dbb9d43   Florian Fainelli   net: dsa: Relocat...
187
  	/*
c362beb07   Vladimir Oltean   net: dsa: Add a p...
188
189
190
191
192
193
  	 * Give the switch driver somewhere to hang its per-port private data
  	 * structures (accessible from the tagger).
  	 */
  	void *priv;
  
  	/*
67dbb9d43   Florian Fainelli   net: dsa: Relocat...
194
195
  	 * Original copy of the master netdev ethtool_ops
  	 */
67dbb9d43   Florian Fainelli   net: dsa: Relocat...
196
  	const struct ethtool_ops *orig_ethtool_ops;
da7b9e9b0   Florian Fainelli   net: dsa: Add ndo...
197
198
199
200
201
  
  	/*
  	 * Original copy of the master netdev net_device_ops
  	 */
  	const struct net_device_ops *orig_ndo_ops;
c8b098086   Andrew Lunn   net: dsa: Add a p...
202
  };
c8f0b8699   Ben Hutchings   dsa: Move all def...
203
  struct dsa_switch {
c33063d6a   Andrew Lunn   dsa: Remove maste...
204
  	struct device *dev;
c8f0b8699   Ben Hutchings   dsa: Move all def...
205
206
207
208
  	/*
  	 * Parent switch tree, and switch index.
  	 */
  	struct dsa_switch_tree	*dst;
99feaafcd   Vivien Didelot   net: dsa: make sw...
209
  	unsigned int		index;
c8f0b8699   Ben Hutchings   dsa: Move all def...
210

f515f192a   Vivien Didelot   net: dsa: add swi...
211
212
  	/* Listener for switch fabric events */
  	struct notifier_block	nb;
c8f0b8699   Ben Hutchings   dsa: Move all def...
213
  	/*
7543a6d53   Andrew Lunn   net: dsa: Have th...
214
215
216
217
218
219
  	 * Give the switch driver somewhere to hang its private data
  	 * structure.
  	 */
  	void *priv;
  
  	/*
c8f0b8699   Ben Hutchings   dsa: Move all def...
220
221
  	 * Configuration data for this switch.
  	 */
ff04955c2   Andrew Lunn   dsa: Rename switc...
222
  	struct dsa_chip_data	*cd;
c8f0b8699   Ben Hutchings   dsa: Move all def...
223
224
  
  	/*
9d490b4ee   Vivien Didelot   net: dsa: rename ...
225
  	 * The switch operations.
c8f0b8699   Ben Hutchings   dsa: Move all def...
226
  	 */
a82f67afe   Florian Fainelli   net: dsa: Make ds...
227
  	const struct dsa_switch_ops	*ops;
c8f0b8699   Ben Hutchings   dsa: Move all def...
228

66472fc04   Andrew Lunn   net: dsa: Copy th...
229
230
231
232
233
234
  	/*
  	 * An array of which element [a] indicates which port on this
  	 * switch should be used to send packets to that are destined
  	 * for switch a. Can be NULL if there is only one switch chip.
  	 */
  	s8		rtable[DSA_MAX_SWITCHES];
c8f0b8699   Ben Hutchings   dsa: Move all def...
235
236
237
  	/*
  	 * Slave mii_bus and devices for the individual ports.
  	 */
0d8bcdd38   Florian Fainelli   net: dsa: allow f...
238
  	u32			phys_mii_mask;
c8f0b8699   Ben Hutchings   dsa: Move all def...
239
  	struct mii_bus		*slave_mii_bus;
a0c02161e   Vivien Didelot   net: dsa: variabl...
240

0f3da6afe   Vivien Didelot   net: dsa: check o...
241
242
243
  	/* Ageing Time limits in msecs */
  	unsigned int ageing_time_min;
  	unsigned int ageing_time_max;
96567d5da   Andrew Lunn   net: dsa: dsa2: A...
244
245
  	/* devlink used to represent this switch device */
  	struct devlink		*devlink;
55199df6d   Florian Fainelli   net: dsa: Allow s...
246
247
  	/* Number of switch port queues */
  	unsigned int		num_tx_queues;
8f5d16f63   Vladimir Oltean   net: dsa: Be awar...
248
249
250
251
  	/* Disallow bridge core from requesting different VLAN awareness
  	 * settings on ports if not hardware-supported
  	 */
  	bool			vlan_filtering_is_global;
145746765   Vladimir Oltean   net: dsa: Keep th...
252
253
254
255
  	/* In case vlan_filtering_is_global is set, the VLAN awareness state
  	 * should be retrieved from here and not from the per-port settings.
  	 */
  	bool			vlan_filtering;
50975b8b3   Vladimir Oltean   net: dsa: Pass pc...
256
257
258
259
  	/* MAC PCS does not provide link state change interrupt, and requires
  	 * polling. Flag passed on to PHYLINK.
  	 */
  	bool			pcs_poll;
a0c02161e   Vivien Didelot   net: dsa: variabl...
260
261
262
  	/* Dynamically allocated ports, keep last */
  	size_t num_ports;
  	struct dsa_port ports[];
c8f0b8699   Ben Hutchings   dsa: Move all def...
263
  };
c38c5a665   Vivien Didelot   net: dsa: use new...
264
  static inline const struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p)
bff7b688d   Vivien Didelot   net: dsa: add dsa...
265
  {
c38c5a665   Vivien Didelot   net: dsa: use new...
266
267
  	return &ds->ports[p];
  }
bff7b688d   Vivien Didelot   net: dsa: add dsa...
268

c38c5a665   Vivien Didelot   net: dsa: use new...
269
270
271
  static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p)
  {
  	return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED;
bff7b688d   Vivien Didelot   net: dsa: add dsa...
272
  }
c8f0b8699   Ben Hutchings   dsa: Move all def...
273
274
  static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
  {
c38c5a665   Vivien Didelot   net: dsa: use new...
275
  	return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_CPU;
c8f0b8699   Ben Hutchings   dsa: Move all def...
276
  }
60045cbfc   Andrew Lunn   net: dsa: Add dsa...
277
278
  static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p)
  {
c38c5a665   Vivien Didelot   net: dsa: use new...
279
  	return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_DSA;
60045cbfc   Andrew Lunn   net: dsa: Add dsa...
280
  }
2b3e9891c   Vivien Didelot   net: dsa: rename ...
281
  static inline bool dsa_is_user_port(struct dsa_switch *ds, int p)
6cd456f38   Vivien Didelot   net: dsa: add dsa...
282
  {
c38c5a665   Vivien Didelot   net: dsa: use new...
283
  	return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_USER;
6cd456f38   Vivien Didelot   net: dsa: add dsa...
284
  }
02bc6e546   Vivien Didelot   net: dsa: introdu...
285
286
  static inline u32 dsa_user_ports(struct dsa_switch *ds)
  {
c38c5a665   Vivien Didelot   net: dsa: use new...
287
288
  	u32 mask = 0;
  	int p;
02bc6e546   Vivien Didelot   net: dsa: introdu...
289

c38c5a665   Vivien Didelot   net: dsa: use new...
290
291
292
293
294
  	for (p = 0; p < ds->num_ports; p++)
  		if (dsa_is_user_port(ds, p))
  			mask |= BIT(p);
  
  	return mask;
c8652c83b   Vivien Didelot   net: dsa: add dsa...
295
  }
3b8fac5d9   Vivien Didelot   net: dsa: introdu...
296
297
298
299
300
301
302
303
304
305
306
  /* Return the local port used to reach an arbitrary switch port */
  static inline unsigned int dsa_towards_port(struct dsa_switch *ds, int device,
  					    int port)
  {
  	if (device == ds->index)
  		return port;
  	else
  		return ds->rtable[device];
  }
  
  /* Return the local port used to reach the dedicated CPU port */
07073c79b   Vivien Didelot   net: dsa: return ...
307
  static inline unsigned int dsa_upstream_port(struct dsa_switch *ds, int port)
c8f0b8699   Ben Hutchings   dsa: Move all def...
308
  {
07073c79b   Vivien Didelot   net: dsa: return ...
309
310
311
312
313
  	const struct dsa_port *dp = dsa_to_port(ds, port);
  	const struct dsa_port *cpu_dp = dp->cpu_dp;
  
  	if (!cpu_dp)
  		return port;
c8f0b8699   Ben Hutchings   dsa: Move all def...
314

3b8fac5d9   Vivien Didelot   net: dsa: introdu...
315
  	return dsa_towards_port(ds, cpu_dp->ds->index, cpu_dp->index);
c8f0b8699   Ben Hutchings   dsa: Move all def...
316
  }
cf2d45f5b   Vladimir Oltean   net: dsa: Add hel...
317
318
319
320
321
322
323
324
325
  static inline bool dsa_port_is_vlan_filtering(const struct dsa_port *dp)
  {
  	const struct dsa_switch *ds = dp->ds;
  
  	if (ds->vlan_filtering_is_global)
  		return ds->vlan_filtering;
  	else
  		return dp->vlan_filtering;
  }
2bedde1ab   Arkadi Sharshevsky   net: dsa: Move FD...
326
327
  typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,
  			      bool is_static, void *data);
9d490b4ee   Vivien Didelot   net: dsa: rename ...
328
  struct dsa_switch_ops {
5ed4e3eb0   Florian Fainelli   net: dsa: Pass a ...
329
330
  	enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds,
  						  int port);
7b314362a   Andrew Lunn   net: dsa: Allow t...
331

c8f0b8699   Ben Hutchings   dsa: Move all def...
332
  	int	(*setup)(struct dsa_switch *ds);
5e3f847a0   Vladimir Oltean   net: dsa: Add tea...
333
  	void	(*teardown)(struct dsa_switch *ds);
6819563e6   Florian Fainelli   net: dsa: allow s...
334
  	u32	(*get_phy_flags)(struct dsa_switch *ds, int port);
c8f0b8699   Ben Hutchings   dsa: Move all def...
335
336
337
338
339
340
341
342
343
  
  	/*
  	 * Access to the switch's PHY registers.
  	 */
  	int	(*phy_read)(struct dsa_switch *ds, int port, int regnum);
  	int	(*phy_write)(struct dsa_switch *ds, int port,
  			     int regnum, u16 val);
  
  	/*
ec9436bae   Florian Fainelli   net: dsa: allow d...
344
345
346
347
  	 * Link state adjustment (called from libphy)
  	 */
  	void	(*adjust_link)(struct dsa_switch *ds, int port,
  				struct phy_device *phydev);
ce31b31c6   Florian Fainelli   net: dsa: allow u...
348
349
  	void	(*fixed_link_update)(struct dsa_switch *ds, int port,
  				struct fixed_phy_status *st);
ec9436bae   Florian Fainelli   net: dsa: allow d...
350
351
  
  	/*
11d8f3dda   Florian Fainelli   net: dsa: Add PHY...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
  	 * PHYLINK integration
  	 */
  	void	(*phylink_validate)(struct dsa_switch *ds, int port,
  				    unsigned long *supported,
  				    struct phylink_link_state *state);
  	int	(*phylink_mac_link_state)(struct dsa_switch *ds, int port,
  					  struct phylink_link_state *state);
  	void	(*phylink_mac_config)(struct dsa_switch *ds, int port,
  				      unsigned int mode,
  				      const struct phylink_link_state *state);
  	void	(*phylink_mac_an_restart)(struct dsa_switch *ds, int port);
  	void	(*phylink_mac_link_down)(struct dsa_switch *ds, int port,
  					 unsigned int mode,
  					 phy_interface_t interface);
  	void	(*phylink_mac_link_up)(struct dsa_switch *ds, int port,
  				       unsigned int mode,
  				       phy_interface_t interface,
  				       struct phy_device *phydev);
  	void	(*phylink_fixed_state)(struct dsa_switch *ds, int port,
  				       struct phylink_link_state *state);
  	/*
c8f0b8699   Ben Hutchings   dsa: Move all def...
373
374
  	 * ethtool hardware statistics.
  	 */
89f090483   Florian Fainelli   net: dsa: Pass st...
375
376
  	void	(*get_strings)(struct dsa_switch *ds, int port,
  			       u32 stringset, uint8_t *data);
c8f0b8699   Ben Hutchings   dsa: Move all def...
377
378
  	void	(*get_ethtool_stats)(struct dsa_switch *ds,
  				     int port, uint64_t *data);
89f090483   Florian Fainelli   net: dsa: Pass st...
379
  	int	(*get_sset_count)(struct dsa_switch *ds, int port, int sset);
cf9635730   Florian Fainelli   net: dsa: Allow p...
380
381
  	void	(*get_ethtool_phy_stats)(struct dsa_switch *ds,
  					 int port, uint64_t *data);
244625491   Florian Fainelli   net: dsa: allow s...
382
383
  
  	/*
19e57c4e6   Florian Fainelli   net: dsa: add {ge...
384
385
386
387
388
389
390
391
  	 * ethtool Wake-on-LAN
  	 */
  	void	(*get_wol)(struct dsa_switch *ds, int port,
  			   struct ethtool_wolinfo *w);
  	int	(*set_wol)(struct dsa_switch *ds, int port,
  			   struct ethtool_wolinfo *w);
  
  	/*
0336369d3   Brandon Streiff   net: dsa: forward...
392
393
394
395
396
397
  	 * ethtool timestamp info
  	 */
  	int	(*get_ts_info)(struct dsa_switch *ds, int port,
  			       struct ethtool_ts_info *ts);
  
  	/*
244625491   Florian Fainelli   net: dsa: allow s...
398
399
400
401
  	 * Suspend and resume
  	 */
  	int	(*suspend)(struct dsa_switch *ds);
  	int	(*resume)(struct dsa_switch *ds);
b2f2af21e   Florian Fainelli   net: dsa: allow e...
402
403
404
405
406
407
  
  	/*
  	 * Port enable/disable
  	 */
  	int	(*port_enable)(struct dsa_switch *ds, int port,
  			       struct phy_device *phy);
75104db0c   Andrew Lunn   dsa: Remove phyde...
408
  	void	(*port_disable)(struct dsa_switch *ds, int port);
7905288f0   Florian Fainelli   net: dsa: allow s...
409
410
  
  	/*
08f500610   Vivien Didelot   net: dsa: rename ...
411
  	 * Port's MAC EEE settings
7905288f0   Florian Fainelli   net: dsa: allow s...
412
  	 */
08f500610   Vivien Didelot   net: dsa: rename ...
413
414
415
416
  	int	(*set_mac_eee)(struct dsa_switch *ds, int port,
  			       struct ethtool_eee *e);
  	int	(*get_mac_eee)(struct dsa_switch *ds, int port,
  			       struct ethtool_eee *e);
51579c3f1   Guenter Roeck   net: dsa: Add sup...
417

6793abb4e   Guenter Roeck   net: dsa: Add sup...
418
419
420
421
422
423
  	/* EEPROM access */
  	int	(*get_eeprom_len)(struct dsa_switch *ds);
  	int	(*get_eeprom)(struct dsa_switch *ds,
  			      struct ethtool_eeprom *eeprom, u8 *data);
  	int	(*set_eeprom)(struct dsa_switch *ds,
  			      struct ethtool_eeprom *eeprom, u8 *data);
3d762a0f0   Guenter Roeck   net: dsa: Add sup...
424
425
426
427
428
429
430
  
  	/*
  	 * Register access.
  	 */
  	int	(*get_regs_len)(struct dsa_switch *ds, int port);
  	void	(*get_regs)(struct dsa_switch *ds, int port,
  			    struct ethtool_regs *regs, void *p);
b73adef67   Florian Fainelli   net: dsa: integra...
431
432
433
434
  
  	/*
  	 * Bridge integration
  	 */
34a79f63b   Vivien Didelot   net: dsa: support...
435
  	int	(*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
71327a4e7   Vivien Didelot   net: dsa: rename ...
436
  	int	(*port_bridge_join)(struct dsa_switch *ds, int port,
a6692754d   Vivien Didelot   net: dsa: pass br...
437
  				    struct net_device *bridge);
f123f2fbe   Vivien Didelot   net: dsa: pass br...
438
439
  	void	(*port_bridge_leave)(struct dsa_switch *ds, int port,
  				     struct net_device *bridge);
43c44a9f6   Vivien Didelot   net: dsa: make th...
440
441
  	void	(*port_stp_state_set)(struct dsa_switch *ds, int port,
  				      u8 state);
732f794c1   Vivien Didelot   net: dsa: add por...
442
  	void	(*port_fast_age)(struct dsa_switch *ds, int port);
57652796a   Russell King   net: dsa: add sup...
443
444
  	int	(*port_egress_floods)(struct dsa_switch *ds, int port,
  				      bool unicast, bool multicast);
2a778e1b5   Vivien Didelot   net: dsa: change ...
445
446
  
  	/*
111495361   Vivien Didelot   net: dsa: add sup...
447
448
  	 * VLAN support
  	 */
fb2dabad6   Vivien Didelot   net: dsa: support...
449
450
  	int	(*port_vlan_filtering)(struct dsa_switch *ds, int port,
  				       bool vlan_filtering);
80e023607   Vivien Didelot   net: dsa: remove ...
451
452
453
454
  	int (*port_vlan_prepare)(struct dsa_switch *ds, int port,
  				 const struct switchdev_obj_port_vlan *vlan);
  	void (*port_vlan_add)(struct dsa_switch *ds, int port,
  			      const struct switchdev_obj_port_vlan *vlan);
76e398a62   Vivien Didelot   net: dsa: use swi...
455
456
  	int	(*port_vlan_del)(struct dsa_switch *ds, int port,
  				 const struct switchdev_obj_port_vlan *vlan);
111495361   Vivien Didelot   net: dsa: add sup...
457
  	/*
2a778e1b5   Vivien Didelot   net: dsa: change ...
458
459
  	 * Forwarding database
  	 */
1b6dd556c   Arkadi Sharshevsky   net: dsa: Remove ...
460
  	int	(*port_fdb_add)(struct dsa_switch *ds, int port,
6c2c1dcb1   Arkadi Sharshevsky   net: dsa: Change ...
461
  				const unsigned char *addr, u16 vid);
2a778e1b5   Vivien Didelot   net: dsa: change ...
462
  	int	(*port_fdb_del)(struct dsa_switch *ds, int port,
6c2c1dcb1   Arkadi Sharshevsky   net: dsa: Change ...
463
  				const unsigned char *addr, u16 vid);
ea70ba980   Vivien Didelot   net: dsa: add por...
464
  	int	(*port_fdb_dump)(struct dsa_switch *ds, int port,
2bedde1ab   Arkadi Sharshevsky   net: dsa: Move FD...
465
  				 dsa_fdb_dump_cb_t *cb, void *data);
8df302552   Vivien Didelot   net: dsa: add MDB...
466
467
468
469
  
  	/*
  	 * Multicast database
  	 */
3709aadc8   Vivien Didelot   net: dsa: remove ...
470
471
472
473
  	int (*port_mdb_prepare)(struct dsa_switch *ds, int port,
  				const struct switchdev_obj_port_mdb *mdb);
  	void (*port_mdb_add)(struct dsa_switch *ds, int port,
  			     const struct switchdev_obj_port_mdb *mdb);
8df302552   Vivien Didelot   net: dsa: add MDB...
474
475
  	int	(*port_mdb_del)(struct dsa_switch *ds, int port,
  				const struct switchdev_obj_port_mdb *mdb);
bf9f26485   Florian Fainelli   net: dsa: Hook {g...
476
477
478
479
480
481
482
  	/*
  	 * RXNFC
  	 */
  	int	(*get_rxnfc)(struct dsa_switch *ds, int port,
  			     struct ethtool_rxnfc *nfc, u32 *rule_locs);
  	int	(*set_rxnfc)(struct dsa_switch *ds, int port,
  			     struct ethtool_rxnfc *nfc);
f50f21274   Florian Fainelli   net: dsa: Add plu...
483
484
485
486
487
488
489
490
491
  
  	/*
  	 * TC integration
  	 */
  	int	(*port_mirror_add)(struct dsa_switch *ds, int port,
  				   struct dsa_mall_mirror_tc_entry *mirror,
  				   bool ingress);
  	void	(*port_mirror_del)(struct dsa_switch *ds, int port,
  				   struct dsa_mall_mirror_tc_entry *mirror);
47d23af29   Vladimir Oltean   net: dsa: Pass nd...
492
493
  	int	(*port_setup_tc)(struct dsa_switch *ds, int port,
  				 enum tc_setup_type type, void *type_data);
40ef2c933   Vivien Didelot   net: dsa: add cro...
494
495
496
497
498
499
500
501
  
  	/*
  	 * Cross-chip operations
  	 */
  	int	(*crosschip_bridge_join)(struct dsa_switch *ds, int sw_index,
  					 int port, struct net_device *br);
  	void	(*crosschip_bridge_leave)(struct dsa_switch *ds, int sw_index,
  					  int port, struct net_device *br);
0336369d3   Brandon Streiff   net: dsa: forward...
502
503
504
505
506
507
508
509
  
  	/*
  	 * PTP functionality
  	 */
  	int	(*port_hwtstamp_get)(struct dsa_switch *ds, int port,
  				     struct ifreq *ifr);
  	int	(*port_hwtstamp_set)(struct dsa_switch *ds, int port,
  				     struct ifreq *ifr);
90af1059c   Brandon Streiff   net: dsa: forward...
510
511
512
513
  	bool	(*port_txtstamp)(struct dsa_switch *ds, int port,
  				 struct sk_buff *clone, unsigned int type);
  	bool	(*port_rxtstamp)(struct dsa_switch *ds, int port,
  				 struct sk_buff *skb, unsigned int type);
97a69a0de   Vladimir Oltean   net: dsa: Add sup...
514
515
516
517
518
519
  
  	/*
  	 * Deferred frame Tx
  	 */
  	netdev_tx_t (*port_deferred_xmit)(struct dsa_switch *ds, int port,
  					  struct sk_buff *skb);
eca0b86bb   Xiaoliang Yang   net: dsa: ocelot:...
520
  	int	(*port_tsn_enable)(struct dsa_port *dp);
c8f0b8699   Ben Hutchings   dsa: Move all def...
521
  };
ab3d408d3   Florian Fainelli   net: dsa: Encapsu...
522
523
  struct dsa_switch_driver {
  	struct list_head	list;
a82f67afe   Florian Fainelli   net: dsa: Make ds...
524
  	const struct dsa_switch_ops *ops;
ab3d408d3   Florian Fainelli   net: dsa: Encapsu...
525
  };
14b89f36e   Florian Fainelli   net: dsa: Rename ...
526
  struct net_device *dsa_dev_to_net_device(struct device *dev);
c8f0b8699   Ben Hutchings   dsa: Move all def...
527

73a7ece8f   Vivien Didelot   net: dsa: comment...
528
  /* Keep inline for faster access in hot path */
c6e970a04   Andrew Lunn   net: break includ...
529
530
531
  static inline bool netdev_uses_dsa(struct net_device *dev)
  {
  #if IS_ENABLED(CONFIG_NET_DSA)
717ffbfb2   Vivien Didelot   net: dsa: remove ...
532
  	return dev->dsa_ptr && dev->dsa_ptr->rcv;
c6e970a04   Andrew Lunn   net: break includ...
533
534
535
  #endif
  	return false;
  }
cc1939e4b   Vladimir Oltean   net: dsa: Allow d...
536
537
538
539
540
541
542
543
  static inline bool dsa_can_decode(const struct sk_buff *skb,
  				  struct net_device *dev)
  {
  #if IS_ENABLED(CONFIG_NET_DSA)
  	return !dev->dsa_ptr->filter || dev->dsa_ptr->filter(skb, dev);
  #endif
  	return false;
  }
a0c02161e   Vivien Didelot   net: dsa: variabl...
544
  struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n);
83c0afaec   Andrew Lunn   net: dsa: Add new...
545
  void dsa_unregister_switch(struct dsa_switch *ds);
23c9ee493   Vivien Didelot   net: dsa: remove ...
546
  int dsa_register_switch(struct dsa_switch *ds);
ea825e70d   Florian Fainelli   net: dsa: Export ...
547
548
549
550
551
552
553
554
555
556
557
558
559
  #ifdef CONFIG_PM_SLEEP
  int dsa_switch_suspend(struct dsa_switch *ds);
  int dsa_switch_resume(struct dsa_switch *ds);
  #else
  static inline int dsa_switch_suspend(struct dsa_switch *ds)
  {
  	return 0;
  }
  static inline int dsa_switch_resume(struct dsa_switch *ds)
  {
  	return 0;
  }
  #endif /* CONFIG_PM_SLEEP */
60724d4ba   Florian Fainelli   net: dsa: Add sup...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
  enum dsa_notifier_type {
  	DSA_PORT_REGISTER,
  	DSA_PORT_UNREGISTER,
  };
  
  struct dsa_notifier_info {
  	struct net_device *dev;
  };
  
  struct dsa_notifier_register_info {
  	struct dsa_notifier_info info;	/* must be first */
  	struct net_device *master;
  	unsigned int port_number;
  	unsigned int switch_number;
  };
  
  static inline struct net_device *
  dsa_notifier_info_to_dev(const struct dsa_notifier_info *info)
  {
  	return info->dev;
  }
  
  #if IS_ENABLED(CONFIG_NET_DSA)
  int register_dsa_notifier(struct notifier_block *nb);
  int unregister_dsa_notifier(struct notifier_block *nb);
  int call_dsa_notifiers(unsigned long val, struct net_device *dev,
  		       struct dsa_notifier_info *info);
  #else
  static inline int register_dsa_notifier(struct notifier_block *nb)
  {
  	return 0;
  }
  
  static inline int unregister_dsa_notifier(struct notifier_block *nb)
  {
  	return 0;
  }
  
  static inline int call_dsa_notifiers(unsigned long val, struct net_device *dev,
  				     struct dsa_notifier_info *info)
  {
  	return NOTIFY_DONE;
  }
  #endif
0a5f14ce6   Florian Fainelli   net: dsa: tag_brc...
604
605
606
607
  /* Broadcom tag specific helpers to insert and extract queue/port number */
  #define BRCM_TAG_SET_PORT_QUEUE(p, q)	((p) << 8 | q)
  #define BRCM_TAG_GET_PORT(v)		((v) >> 8)
  #define BRCM_TAG_GET_QUEUE(v)		((v) & 0xff)
cf9635730   Florian Fainelli   net: dsa: Allow p...
608

97a69a0de   Vladimir Oltean   net: dsa: Add sup...
609
  netdev_tx_t dsa_enqueue_skb(struct sk_buff *skb, struct net_device *dev);
cf9635730   Florian Fainelli   net: dsa: Allow p...
610
611
612
  int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data);
  int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data);
  int dsa_port_get_phy_sset_count(struct dsa_port *dp);
11d8f3dda   Florian Fainelli   net: dsa: Add PHY...
613
  void dsa_port_phylink_mac_change(struct dsa_switch *ds, int port, bool up);
cf9635730   Florian Fainelli   net: dsa: Allow p...
614

d3b8c0498   Andrew Lunn   dsa: Add boilerpl...
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
  struct dsa_tag_driver {
  	const struct dsa_device_ops *ops;
  	struct list_head list;
  	struct module *owner;
  };
  
  void dsa_tag_drivers_register(struct dsa_tag_driver *dsa_tag_driver_array[],
  			      unsigned int count,
  			      struct module *owner);
  void dsa_tag_drivers_unregister(struct dsa_tag_driver *dsa_tag_driver_array[],
  				unsigned int count);
  
  #define dsa_tag_driver_module_drivers(__dsa_tag_drivers_array, __count)	\
  static int __init dsa_tag_driver_module_init(void)			\
  {									\
  	dsa_tag_drivers_register(__dsa_tag_drivers_array, __count,	\
  				 THIS_MODULE);				\
  	return 0;							\
  }									\
  module_init(dsa_tag_driver_module_init);				\
  									\
  static void __exit dsa_tag_driver_module_exit(void)			\
  {									\
  	dsa_tag_drivers_unregister(__dsa_tag_drivers_array, __count);	\
  }									\
  module_exit(dsa_tag_driver_module_exit)
  
  /**
   * module_dsa_tag_drivers() - Helper macro for registering DSA tag
   * drivers
   * @__ops_array: Array of tag driver strucutres
   *
   * Helper macro for DSA tag drivers which do not do anything special
   * in module init/exit. Each module may only use this macro once, and
   * calling it replaces module_init() and module_exit().
   */
  #define module_dsa_tag_drivers(__ops_array)				\
  dsa_tag_driver_module_drivers(__ops_array, ARRAY_SIZE(__ops_array))
  
  #define DSA_TAG_DRIVER_NAME(__ops) dsa_tag_driver ## _ ## __ops
  
  /* Create a static structure we can build a linked list of dsa_tag
   * drivers
   */
  #define DSA_TAG_DRIVER(__ops)						\
  static struct dsa_tag_driver DSA_TAG_DRIVER_NAME(__ops) = {		\
  	.ops = &__ops,							\
  }
  
  /**
   * module_dsa_tag_driver() - Helper macro for registering a single DSA tag
   * driver
   * @__ops: Single tag driver structures
   *
   * Helper macro for DSA tag drivers which do not do anything special
   * in module init/exit. Each module may only use this macro once, and
   * calling it replaces module_init() and module_exit().
   */
  #define module_dsa_tag_driver(__ops)					\
  DSA_TAG_DRIVER(__ops);							\
  									\
  static struct dsa_tag_driver *dsa_tag_driver_array[] =	{		\
  	&DSA_TAG_DRIVER_NAME(__ops)					\
  };									\
  module_dsa_tag_drivers(dsa_tag_driver_array)
91da11f87   Lennert Buytenhek   net: Distributed ...
680
  #endif
d3b8c0498   Andrew Lunn   dsa: Add boilerpl...
681