.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* |
---|
2 | 3 | * include/net/dsa.h - Driver for Distributed Switch Architecture switch chips |
---|
3 | 4 | * Copyright (c) 2008-2009 Marvell Semiconductor |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify |
---|
6 | | - * it under the terms of the GNU General Public License as published by |
---|
7 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
8 | | - * (at your option) any later version. |
---|
9 | 5 | */ |
---|
10 | 6 | |
---|
11 | 7 | #ifndef __LINUX_NET_DSA_H |
---|
.. | .. |
---|
21 | 17 | #include <linux/ethtool.h> |
---|
22 | 18 | #include <linux/net_tstamp.h> |
---|
23 | 19 | #include <linux/phy.h> |
---|
| 20 | +#include <linux/platform_data/dsa.h> |
---|
| 21 | +#include <linux/phylink.h> |
---|
24 | 22 | #include <net/devlink.h> |
---|
25 | 23 | #include <net/switchdev.h> |
---|
26 | 24 | |
---|
.. | .. |
---|
29 | 27 | struct fixed_phy_status; |
---|
30 | 28 | struct phylink_link_state; |
---|
31 | 29 | |
---|
| 30 | +#define DSA_TAG_PROTO_NONE_VALUE 0 |
---|
| 31 | +#define DSA_TAG_PROTO_BRCM_VALUE 1 |
---|
| 32 | +#define DSA_TAG_PROTO_BRCM_PREPEND_VALUE 2 |
---|
| 33 | +#define DSA_TAG_PROTO_DSA_VALUE 3 |
---|
| 34 | +#define DSA_TAG_PROTO_EDSA_VALUE 4 |
---|
| 35 | +#define DSA_TAG_PROTO_GSWIP_VALUE 5 |
---|
| 36 | +#define DSA_TAG_PROTO_KSZ9477_VALUE 6 |
---|
| 37 | +#define DSA_TAG_PROTO_KSZ9893_VALUE 7 |
---|
| 38 | +#define DSA_TAG_PROTO_LAN9303_VALUE 8 |
---|
| 39 | +#define DSA_TAG_PROTO_MTK_VALUE 9 |
---|
| 40 | +#define DSA_TAG_PROTO_QCA_VALUE 10 |
---|
| 41 | +#define DSA_TAG_PROTO_TRAILER_VALUE 11 |
---|
| 42 | +#define DSA_TAG_PROTO_8021Q_VALUE 12 |
---|
| 43 | +#define DSA_TAG_PROTO_SJA1105_VALUE 13 |
---|
| 44 | +#define DSA_TAG_PROTO_KSZ8795_VALUE 14 |
---|
| 45 | +#define DSA_TAG_PROTO_OCELOT_VALUE 15 |
---|
| 46 | +#define DSA_TAG_PROTO_AR9331_VALUE 16 |
---|
| 47 | +#define DSA_TAG_PROTO_RTL4_A_VALUE 17 |
---|
| 48 | + |
---|
32 | 49 | enum dsa_tag_protocol { |
---|
33 | | - DSA_TAG_PROTO_NONE = 0, |
---|
34 | | - DSA_TAG_PROTO_BRCM, |
---|
35 | | - DSA_TAG_PROTO_BRCM_PREPEND, |
---|
36 | | - DSA_TAG_PROTO_DSA, |
---|
37 | | - DSA_TAG_PROTO_EDSA, |
---|
38 | | - DSA_TAG_PROTO_KSZ, |
---|
39 | | - DSA_TAG_PROTO_LAN9303, |
---|
40 | | - DSA_TAG_PROTO_MTK, |
---|
41 | | - DSA_TAG_PROTO_QCA, |
---|
42 | | - DSA_TAG_PROTO_TRAILER, |
---|
43 | | - DSA_TAG_LAST, /* MUST BE LAST */ |
---|
44 | | -}; |
---|
45 | | - |
---|
46 | | -#define DSA_MAX_SWITCHES 4 |
---|
47 | | -#define DSA_MAX_PORTS 12 |
---|
48 | | - |
---|
49 | | -#define DSA_RTABLE_NONE -1 |
---|
50 | | - |
---|
51 | | -struct dsa_chip_data { |
---|
52 | | - /* |
---|
53 | | - * How to access the switch configuration registers. |
---|
54 | | - */ |
---|
55 | | - struct device *host_dev; |
---|
56 | | - int sw_addr; |
---|
57 | | - |
---|
58 | | - /* |
---|
59 | | - * Reference to network devices |
---|
60 | | - */ |
---|
61 | | - struct device *netdev[DSA_MAX_PORTS]; |
---|
62 | | - |
---|
63 | | - /* set to size of eeprom if supported by the switch */ |
---|
64 | | - int eeprom_len; |
---|
65 | | - |
---|
66 | | - /* Device tree node pointer for this specific switch chip |
---|
67 | | - * used during switch setup in case additional properties |
---|
68 | | - * and resources needs to be used |
---|
69 | | - */ |
---|
70 | | - struct device_node *of_node; |
---|
71 | | - |
---|
72 | | - /* |
---|
73 | | - * The names of the switch's ports. Use "cpu" to |
---|
74 | | - * designate the switch port that the cpu is connected to, |
---|
75 | | - * "dsa" to indicate that this port is a DSA link to |
---|
76 | | - * another switch, NULL to indicate the port is unused, |
---|
77 | | - * or any other string to indicate this is a physical port. |
---|
78 | | - */ |
---|
79 | | - char *port_names[DSA_MAX_PORTS]; |
---|
80 | | - struct device_node *port_dn[DSA_MAX_PORTS]; |
---|
81 | | - |
---|
82 | | - /* |
---|
83 | | - * An array of which element [a] indicates which port on this |
---|
84 | | - * switch should be used to send packets to that are destined |
---|
85 | | - * for switch a. Can be NULL if there is only one switch chip. |
---|
86 | | - */ |
---|
87 | | - s8 rtable[DSA_MAX_SWITCHES]; |
---|
88 | | -}; |
---|
89 | | - |
---|
90 | | -struct dsa_platform_data { |
---|
91 | | - /* |
---|
92 | | - * Reference to a Linux network interface that connects |
---|
93 | | - * to the root switch chip of the tree. |
---|
94 | | - */ |
---|
95 | | - struct device *netdev; |
---|
96 | | - struct net_device *of_netdev; |
---|
97 | | - |
---|
98 | | - /* |
---|
99 | | - * Info structs describing each of the switch chips |
---|
100 | | - * connected via this network interface. |
---|
101 | | - */ |
---|
102 | | - int nr_chips; |
---|
103 | | - struct dsa_chip_data *chip; |
---|
| 50 | + DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, |
---|
| 51 | + DSA_TAG_PROTO_BRCM = DSA_TAG_PROTO_BRCM_VALUE, |
---|
| 52 | + DSA_TAG_PROTO_BRCM_PREPEND = DSA_TAG_PROTO_BRCM_PREPEND_VALUE, |
---|
| 53 | + DSA_TAG_PROTO_DSA = DSA_TAG_PROTO_DSA_VALUE, |
---|
| 54 | + DSA_TAG_PROTO_EDSA = DSA_TAG_PROTO_EDSA_VALUE, |
---|
| 55 | + DSA_TAG_PROTO_GSWIP = DSA_TAG_PROTO_GSWIP_VALUE, |
---|
| 56 | + DSA_TAG_PROTO_KSZ9477 = DSA_TAG_PROTO_KSZ9477_VALUE, |
---|
| 57 | + DSA_TAG_PROTO_KSZ9893 = DSA_TAG_PROTO_KSZ9893_VALUE, |
---|
| 58 | + DSA_TAG_PROTO_LAN9303 = DSA_TAG_PROTO_LAN9303_VALUE, |
---|
| 59 | + DSA_TAG_PROTO_MTK = DSA_TAG_PROTO_MTK_VALUE, |
---|
| 60 | + DSA_TAG_PROTO_QCA = DSA_TAG_PROTO_QCA_VALUE, |
---|
| 61 | + DSA_TAG_PROTO_TRAILER = DSA_TAG_PROTO_TRAILER_VALUE, |
---|
| 62 | + DSA_TAG_PROTO_8021Q = DSA_TAG_PROTO_8021Q_VALUE, |
---|
| 63 | + DSA_TAG_PROTO_SJA1105 = DSA_TAG_PROTO_SJA1105_VALUE, |
---|
| 64 | + DSA_TAG_PROTO_KSZ8795 = DSA_TAG_PROTO_KSZ8795_VALUE, |
---|
| 65 | + DSA_TAG_PROTO_OCELOT = DSA_TAG_PROTO_OCELOT_VALUE, |
---|
| 66 | + DSA_TAG_PROTO_AR9331 = DSA_TAG_PROTO_AR9331_VALUE, |
---|
| 67 | + DSA_TAG_PROTO_RTL4_A = DSA_TAG_PROTO_RTL4_A_VALUE, |
---|
104 | 68 | }; |
---|
105 | 69 | |
---|
106 | 70 | struct packet_type; |
---|
.. | .. |
---|
110 | 74 | struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); |
---|
111 | 75 | struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, |
---|
112 | 76 | struct packet_type *pt); |
---|
113 | | - int (*flow_dissect)(const struct sk_buff *skb, __be16 *proto, |
---|
114 | | - int *offset); |
---|
| 77 | + void (*flow_dissect)(const struct sk_buff *skb, __be16 *proto, |
---|
| 78 | + int *offset); |
---|
| 79 | + /* Used to determine which traffic should match the DSA filter in |
---|
| 80 | + * eth_type_trans, and which, if any, should bypass it and be processed |
---|
| 81 | + * as regular on the master net device. |
---|
| 82 | + */ |
---|
| 83 | + bool (*filter)(const struct sk_buff *skb, struct net_device *dev); |
---|
| 84 | + unsigned int overhead; |
---|
| 85 | + const char *name; |
---|
| 86 | + enum dsa_tag_protocol proto; |
---|
| 87 | + /* Some tagging protocols either mangle or shift the destination MAC |
---|
| 88 | + * address, in which case the DSA master would drop packets on ingress |
---|
| 89 | + * if what it understands out of the destination MAC address is not in |
---|
| 90 | + * its RX filter. |
---|
| 91 | + */ |
---|
| 92 | + bool promisc_on_master; |
---|
| 93 | + bool tail_tag; |
---|
115 | 94 | }; |
---|
| 95 | + |
---|
| 96 | +/* This structure defines the control interfaces that are overlayed by the |
---|
| 97 | + * DSA layer on top of the DSA CPU/management net_device instance. This is |
---|
| 98 | + * used by the core net_device layer while calling various net_device_ops |
---|
| 99 | + * function pointers. |
---|
| 100 | + */ |
---|
| 101 | +struct dsa_netdevice_ops { |
---|
| 102 | + int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, |
---|
| 103 | + int cmd); |
---|
| 104 | +}; |
---|
| 105 | + |
---|
| 106 | +#define DSA_TAG_DRIVER_ALIAS "dsa_tag-" |
---|
| 107 | +#define MODULE_ALIAS_DSA_TAG_DRIVER(__proto) \ |
---|
| 108 | + MODULE_ALIAS(DSA_TAG_DRIVER_ALIAS __stringify(__proto##_VALUE)) |
---|
| 109 | + |
---|
| 110 | +struct dsa_skb_cb { |
---|
| 111 | + struct sk_buff *clone; |
---|
| 112 | +}; |
---|
| 113 | + |
---|
| 114 | +struct __dsa_skb_cb { |
---|
| 115 | + struct dsa_skb_cb cb; |
---|
| 116 | + u8 priv[48 - sizeof(struct dsa_skb_cb)]; |
---|
| 117 | +}; |
---|
| 118 | + |
---|
| 119 | +#define DSA_SKB_CB(skb) ((struct dsa_skb_cb *)((skb)->cb)) |
---|
| 120 | + |
---|
| 121 | +#define DSA_SKB_CB_PRIV(skb) \ |
---|
| 122 | + ((void *)(skb)->cb + offsetof(struct __dsa_skb_cb, priv)) |
---|
116 | 123 | |
---|
117 | 124 | struct dsa_switch_tree { |
---|
118 | 125 | struct list_head list; |
---|
.. | .. |
---|
135 | 142 | */ |
---|
136 | 143 | struct dsa_platform_data *pd; |
---|
137 | 144 | |
---|
138 | | - /* |
---|
139 | | - * The switch port to which the CPU is attached. |
---|
140 | | - */ |
---|
141 | | - struct dsa_port *cpu_dp; |
---|
| 145 | + /* List of switch ports */ |
---|
| 146 | + struct list_head ports; |
---|
142 | 147 | |
---|
143 | | - /* |
---|
144 | | - * Data for the individual switch chips. |
---|
145 | | - */ |
---|
146 | | - struct dsa_switch *ds[DSA_MAX_SWITCHES]; |
---|
| 148 | + /* List of DSA links composing the routing table */ |
---|
| 149 | + struct list_head rtable; |
---|
147 | 150 | }; |
---|
148 | 151 | |
---|
149 | | -/* TC matchall action types, only mirroring for now */ |
---|
| 152 | +/* TC matchall action types */ |
---|
150 | 153 | enum dsa_port_mall_action_type { |
---|
151 | 154 | DSA_PORT_MALL_MIRROR, |
---|
| 155 | + DSA_PORT_MALL_POLICER, |
---|
152 | 156 | }; |
---|
153 | 157 | |
---|
154 | 158 | /* TC mirroring entry */ |
---|
155 | 159 | struct dsa_mall_mirror_tc_entry { |
---|
156 | 160 | u8 to_local_port; |
---|
157 | 161 | bool ingress; |
---|
| 162 | +}; |
---|
| 163 | + |
---|
| 164 | +/* TC port policer entry */ |
---|
| 165 | +struct dsa_mall_policer_tc_entry { |
---|
| 166 | + u32 burst; |
---|
| 167 | + u64 rate_bytes_per_sec; |
---|
158 | 168 | }; |
---|
159 | 169 | |
---|
160 | 170 | /* TC matchall entry */ |
---|
.. | .. |
---|
164 | 174 | enum dsa_port_mall_action_type type; |
---|
165 | 175 | union { |
---|
166 | 176 | struct dsa_mall_mirror_tc_entry mirror; |
---|
| 177 | + struct dsa_mall_policer_tc_entry policer; |
---|
167 | 178 | }; |
---|
168 | 179 | }; |
---|
169 | 180 | |
---|
.. | .. |
---|
184 | 195 | struct dsa_switch_tree *dst; |
---|
185 | 196 | struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, |
---|
186 | 197 | struct packet_type *pt); |
---|
| 198 | + bool (*filter)(const struct sk_buff *skb, struct net_device *dev); |
---|
187 | 199 | |
---|
188 | 200 | enum { |
---|
189 | 201 | DSA_PORT_TYPE_UNUSED = 0, |
---|
.. | .. |
---|
195 | 207 | struct dsa_switch *ds; |
---|
196 | 208 | unsigned int index; |
---|
197 | 209 | const char *name; |
---|
198 | | - const struct dsa_port *cpu_dp; |
---|
| 210 | + struct dsa_port *cpu_dp; |
---|
199 | 211 | const char *mac; |
---|
200 | 212 | struct device_node *dn; |
---|
201 | 213 | unsigned int ageing_time; |
---|
| 214 | + bool vlan_filtering; |
---|
202 | 215 | u8 stp_state; |
---|
203 | 216 | struct net_device *bridge_dev; |
---|
204 | 217 | struct devlink_port devlink_port; |
---|
| 218 | + bool devlink_port_setup; |
---|
205 | 219 | struct phylink *pl; |
---|
| 220 | + struct phylink_config pl_config; |
---|
| 221 | + |
---|
| 222 | + struct list_head list; |
---|
| 223 | + |
---|
| 224 | + /* |
---|
| 225 | + * Give the switch driver somewhere to hang its per-port private data |
---|
| 226 | + * structures (accessible from the tagger). |
---|
| 227 | + */ |
---|
| 228 | + void *priv; |
---|
| 229 | + |
---|
206 | 230 | /* |
---|
207 | 231 | * Original copy of the master netdev ethtool_ops |
---|
208 | 232 | */ |
---|
209 | 233 | const struct ethtool_ops *orig_ethtool_ops; |
---|
| 234 | + |
---|
| 235 | + /* |
---|
| 236 | + * Original copy of the master netdev net_device_ops |
---|
| 237 | + */ |
---|
| 238 | + const struct dsa_netdevice_ops *netdev_ops; |
---|
| 239 | + |
---|
| 240 | + bool setup; |
---|
| 241 | +}; |
---|
| 242 | + |
---|
| 243 | +/* TODO: ideally DSA ports would have a single dp->link_dp member, |
---|
| 244 | + * and no dst->rtable nor this struct dsa_link would be needed, |
---|
| 245 | + * but this would require some more complex tree walking, |
---|
| 246 | + * so keep it stupid at the moment and list them all. |
---|
| 247 | + */ |
---|
| 248 | +struct dsa_link { |
---|
| 249 | + struct dsa_port *dp; |
---|
| 250 | + struct dsa_port *link_dp; |
---|
| 251 | + struct list_head list; |
---|
210 | 252 | }; |
---|
211 | 253 | |
---|
212 | 254 | struct dsa_switch { |
---|
| 255 | + bool setup; |
---|
| 256 | + |
---|
213 | 257 | struct device *dev; |
---|
214 | 258 | |
---|
215 | 259 | /* |
---|
.. | .. |
---|
238 | 282 | const struct dsa_switch_ops *ops; |
---|
239 | 283 | |
---|
240 | 284 | /* |
---|
241 | | - * An array of which element [a] indicates which port on this |
---|
242 | | - * switch should be used to send packets to that are destined |
---|
243 | | - * for switch a. Can be NULL if there is only one switch chip. |
---|
244 | | - */ |
---|
245 | | - s8 rtable[DSA_MAX_SWITCHES]; |
---|
246 | | - |
---|
247 | | - /* |
---|
248 | 285 | * Slave mii_bus and devices for the individual ports. |
---|
249 | 286 | */ |
---|
250 | 287 | u32 phys_mii_mask; |
---|
.. | .. |
---|
260 | 297 | /* Number of switch port queues */ |
---|
261 | 298 | unsigned int num_tx_queues; |
---|
262 | 299 | |
---|
263 | | - unsigned long *bitmap; |
---|
264 | | - unsigned long _bitmap; |
---|
| 300 | + /* Disallow bridge core from requesting different VLAN awareness |
---|
| 301 | + * settings on ports if not hardware-supported |
---|
| 302 | + */ |
---|
| 303 | + bool vlan_filtering_is_global; |
---|
265 | 304 | |
---|
266 | | - /* Dynamically allocated ports, keep last */ |
---|
| 305 | + /* Pass .port_vlan_add and .port_vlan_del to drivers even for bridges |
---|
| 306 | + * that have vlan_filtering=0. All drivers should ideally set this (and |
---|
| 307 | + * then the option would get removed), but it is unknown whether this |
---|
| 308 | + * would break things or not. |
---|
| 309 | + */ |
---|
| 310 | + bool configure_vlan_while_not_filtering; |
---|
| 311 | + |
---|
| 312 | + /* If the switch driver always programs the CPU port as egress tagged |
---|
| 313 | + * despite the VLAN configuration indicating otherwise, then setting |
---|
| 314 | + * @untag_bridge_pvid will force the DSA receive path to pop the bridge's |
---|
| 315 | + * default_pvid VLAN tagged frames to offer a consistent behavior |
---|
| 316 | + * between a vlan_filtering=0 and vlan_filtering=1 bridge device. |
---|
| 317 | + */ |
---|
| 318 | + bool untag_bridge_pvid; |
---|
| 319 | + |
---|
| 320 | + /* In case vlan_filtering_is_global is set, the VLAN awareness state |
---|
| 321 | + * should be retrieved from here and not from the per-port settings. |
---|
| 322 | + */ |
---|
| 323 | + bool vlan_filtering; |
---|
| 324 | + |
---|
| 325 | + /* MAC PCS does not provide link state change interrupt, and requires |
---|
| 326 | + * polling. Flag passed on to PHYLINK. |
---|
| 327 | + */ |
---|
| 328 | + bool pcs_poll; |
---|
| 329 | + |
---|
| 330 | + /* For switches that only have the MRU configurable. To ensure the |
---|
| 331 | + * configured MTU is not exceeded, normalization of MRU on all bridged |
---|
| 332 | + * interfaces is needed. |
---|
| 333 | + */ |
---|
| 334 | + bool mtu_enforcement_ingress; |
---|
| 335 | + |
---|
267 | 336 | size_t num_ports; |
---|
268 | | - struct dsa_port ports[]; |
---|
269 | 337 | }; |
---|
270 | 338 | |
---|
271 | | -static inline const struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p) |
---|
| 339 | +static inline struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p) |
---|
272 | 340 | { |
---|
273 | | - return &ds->ports[p]; |
---|
| 341 | + struct dsa_switch_tree *dst = ds->dst; |
---|
| 342 | + struct dsa_port *dp; |
---|
| 343 | + |
---|
| 344 | + list_for_each_entry(dp, &dst->ports, list) |
---|
| 345 | + if (dp->ds == ds && dp->index == p) |
---|
| 346 | + return dp; |
---|
| 347 | + |
---|
| 348 | + return NULL; |
---|
274 | 349 | } |
---|
275 | 350 | |
---|
276 | 351 | static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p) |
---|
.. | .. |
---|
305 | 380 | return mask; |
---|
306 | 381 | } |
---|
307 | 382 | |
---|
| 383 | +/* Return the local port used to reach an arbitrary switch device */ |
---|
| 384 | +static inline unsigned int dsa_routing_port(struct dsa_switch *ds, int device) |
---|
| 385 | +{ |
---|
| 386 | + struct dsa_switch_tree *dst = ds->dst; |
---|
| 387 | + struct dsa_link *dl; |
---|
| 388 | + |
---|
| 389 | + list_for_each_entry(dl, &dst->rtable, list) |
---|
| 390 | + if (dl->dp->ds == ds && dl->link_dp->ds->index == device) |
---|
| 391 | + return dl->dp->index; |
---|
| 392 | + |
---|
| 393 | + return ds->num_ports; |
---|
| 394 | +} |
---|
| 395 | + |
---|
308 | 396 | /* Return the local port used to reach an arbitrary switch port */ |
---|
309 | 397 | static inline unsigned int dsa_towards_port(struct dsa_switch *ds, int device, |
---|
310 | 398 | int port) |
---|
.. | .. |
---|
312 | 400 | if (device == ds->index) |
---|
313 | 401 | return port; |
---|
314 | 402 | else |
---|
315 | | - return ds->rtable[device]; |
---|
| 403 | + return dsa_routing_port(ds, device); |
---|
316 | 404 | } |
---|
317 | 405 | |
---|
318 | 406 | /* Return the local port used to reach the dedicated CPU port */ |
---|
.. | .. |
---|
327 | 415 | return dsa_towards_port(ds, cpu_dp->ds->index, cpu_dp->index); |
---|
328 | 416 | } |
---|
329 | 417 | |
---|
| 418 | +static inline bool dsa_port_is_vlan_filtering(const struct dsa_port *dp) |
---|
| 419 | +{ |
---|
| 420 | + const struct dsa_switch *ds = dp->ds; |
---|
| 421 | + |
---|
| 422 | + if (ds->vlan_filtering_is_global) |
---|
| 423 | + return ds->vlan_filtering; |
---|
| 424 | + else |
---|
| 425 | + return dp->vlan_filtering; |
---|
| 426 | +} |
---|
| 427 | + |
---|
330 | 428 | typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid, |
---|
331 | 429 | bool is_static, void *data); |
---|
332 | 430 | struct dsa_switch_ops { |
---|
333 | | -#if IS_ENABLED(CONFIG_NET_DSA_LEGACY) |
---|
334 | | - /* |
---|
335 | | - * Legacy probing. |
---|
336 | | - */ |
---|
337 | | - const char *(*probe)(struct device *dsa_dev, |
---|
338 | | - struct device *host_dev, int sw_addr, |
---|
339 | | - void **priv); |
---|
340 | | -#endif |
---|
341 | | - |
---|
342 | 431 | enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds, |
---|
343 | | - int port); |
---|
| 432 | + int port, |
---|
| 433 | + enum dsa_tag_protocol mprot); |
---|
344 | 434 | |
---|
345 | 435 | int (*setup)(struct dsa_switch *ds); |
---|
| 436 | + void (*teardown)(struct dsa_switch *ds); |
---|
346 | 437 | u32 (*get_phy_flags)(struct dsa_switch *ds, int port); |
---|
347 | 438 | |
---|
348 | 439 | /* |
---|
.. | .. |
---|
378 | 469 | void (*phylink_mac_link_up)(struct dsa_switch *ds, int port, |
---|
379 | 470 | unsigned int mode, |
---|
380 | 471 | phy_interface_t interface, |
---|
381 | | - struct phy_device *phydev); |
---|
| 472 | + struct phy_device *phydev, |
---|
| 473 | + int speed, int duplex, |
---|
| 474 | + bool tx_pause, bool rx_pause); |
---|
382 | 475 | void (*phylink_fixed_state)(struct dsa_switch *ds, int port, |
---|
383 | 476 | struct phylink_link_state *state); |
---|
384 | 477 | /* |
---|
.. | .. |
---|
417 | 510 | */ |
---|
418 | 511 | int (*port_enable)(struct dsa_switch *ds, int port, |
---|
419 | 512 | struct phy_device *phy); |
---|
420 | | - void (*port_disable)(struct dsa_switch *ds, int port, |
---|
421 | | - struct phy_device *phy); |
---|
| 513 | + void (*port_disable)(struct dsa_switch *ds, int port); |
---|
422 | 514 | |
---|
423 | 515 | /* |
---|
424 | 516 | * Port's MAC EEE settings |
---|
.. | .. |
---|
453 | 545 | void (*port_stp_state_set)(struct dsa_switch *ds, int port, |
---|
454 | 546 | u8 state); |
---|
455 | 547 | void (*port_fast_age)(struct dsa_switch *ds, int port); |
---|
| 548 | + int (*port_egress_floods)(struct dsa_switch *ds, int port, |
---|
| 549 | + bool unicast, bool multicast); |
---|
456 | 550 | |
---|
457 | 551 | /* |
---|
458 | 552 | * VLAN support |
---|
459 | 553 | */ |
---|
460 | 554 | int (*port_vlan_filtering)(struct dsa_switch *ds, int port, |
---|
461 | | - bool vlan_filtering); |
---|
| 555 | + bool vlan_filtering, |
---|
| 556 | + struct switchdev_trans *trans); |
---|
462 | 557 | int (*port_vlan_prepare)(struct dsa_switch *ds, int port, |
---|
463 | 558 | const struct switchdev_obj_port_vlan *vlan); |
---|
464 | 559 | void (*port_vlan_add)(struct dsa_switch *ds, int port, |
---|
.. | .. |
---|
495 | 590 | /* |
---|
496 | 591 | * TC integration |
---|
497 | 592 | */ |
---|
| 593 | + int (*cls_flower_add)(struct dsa_switch *ds, int port, |
---|
| 594 | + struct flow_cls_offload *cls, bool ingress); |
---|
| 595 | + int (*cls_flower_del)(struct dsa_switch *ds, int port, |
---|
| 596 | + struct flow_cls_offload *cls, bool ingress); |
---|
| 597 | + int (*cls_flower_stats)(struct dsa_switch *ds, int port, |
---|
| 598 | + struct flow_cls_offload *cls, bool ingress); |
---|
498 | 599 | int (*port_mirror_add)(struct dsa_switch *ds, int port, |
---|
499 | 600 | struct dsa_mall_mirror_tc_entry *mirror, |
---|
500 | 601 | bool ingress); |
---|
501 | 602 | void (*port_mirror_del)(struct dsa_switch *ds, int port, |
---|
502 | 603 | struct dsa_mall_mirror_tc_entry *mirror); |
---|
| 604 | + int (*port_policer_add)(struct dsa_switch *ds, int port, |
---|
| 605 | + struct dsa_mall_policer_tc_entry *policer); |
---|
| 606 | + void (*port_policer_del)(struct dsa_switch *ds, int port); |
---|
| 607 | + int (*port_setup_tc)(struct dsa_switch *ds, int port, |
---|
| 608 | + enum tc_setup_type type, void *type_data); |
---|
503 | 609 | |
---|
504 | 610 | /* |
---|
505 | 611 | * Cross-chip operations |
---|
506 | 612 | */ |
---|
507 | | - int (*crosschip_bridge_join)(struct dsa_switch *ds, int sw_index, |
---|
508 | | - int port, struct net_device *br); |
---|
509 | | - void (*crosschip_bridge_leave)(struct dsa_switch *ds, int sw_index, |
---|
510 | | - int port, struct net_device *br); |
---|
| 613 | + int (*crosschip_bridge_join)(struct dsa_switch *ds, int tree_index, |
---|
| 614 | + int sw_index, int port, |
---|
| 615 | + struct net_device *br); |
---|
| 616 | + void (*crosschip_bridge_leave)(struct dsa_switch *ds, int tree_index, |
---|
| 617 | + int sw_index, int port, |
---|
| 618 | + struct net_device *br); |
---|
511 | 619 | |
---|
512 | 620 | /* |
---|
513 | 621 | * PTP functionality |
---|
.. | .. |
---|
520 | 628 | struct sk_buff *clone, unsigned int type); |
---|
521 | 629 | bool (*port_rxtstamp)(struct dsa_switch *ds, int port, |
---|
522 | 630 | struct sk_buff *skb, unsigned int type); |
---|
| 631 | + |
---|
| 632 | + /* Devlink parameters, etc */ |
---|
| 633 | + int (*devlink_param_get)(struct dsa_switch *ds, u32 id, |
---|
| 634 | + struct devlink_param_gset_ctx *ctx); |
---|
| 635 | + int (*devlink_param_set)(struct dsa_switch *ds, u32 id, |
---|
| 636 | + struct devlink_param_gset_ctx *ctx); |
---|
| 637 | + int (*devlink_info_get)(struct dsa_switch *ds, |
---|
| 638 | + struct devlink_info_req *req, |
---|
| 639 | + struct netlink_ext_ack *extack); |
---|
| 640 | + |
---|
| 641 | + /* |
---|
| 642 | + * MTU change functionality. Switches can also adjust their MRU through |
---|
| 643 | + * this method. By MTU, one understands the SDU (L2 payload) length. |
---|
| 644 | + * If the switch needs to account for the DSA tag on the CPU port, this |
---|
| 645 | + * method needs to do so privately. |
---|
| 646 | + */ |
---|
| 647 | + int (*port_change_mtu)(struct dsa_switch *ds, int port, |
---|
| 648 | + int new_mtu); |
---|
| 649 | + int (*port_max_mtu)(struct dsa_switch *ds, int port); |
---|
523 | 650 | }; |
---|
| 651 | + |
---|
| 652 | +#define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \ |
---|
| 653 | + DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes, \ |
---|
| 654 | + dsa_devlink_param_get, dsa_devlink_param_set, NULL) |
---|
| 655 | + |
---|
| 656 | +int dsa_devlink_param_get(struct devlink *dl, u32 id, |
---|
| 657 | + struct devlink_param_gset_ctx *ctx); |
---|
| 658 | +int dsa_devlink_param_set(struct devlink *dl, u32 id, |
---|
| 659 | + struct devlink_param_gset_ctx *ctx); |
---|
| 660 | +int dsa_devlink_params_register(struct dsa_switch *ds, |
---|
| 661 | + const struct devlink_param *params, |
---|
| 662 | + size_t params_count); |
---|
| 663 | +void dsa_devlink_params_unregister(struct dsa_switch *ds, |
---|
| 664 | + const struct devlink_param *params, |
---|
| 665 | + size_t params_count); |
---|
| 666 | +int dsa_devlink_resource_register(struct dsa_switch *ds, |
---|
| 667 | + const char *resource_name, |
---|
| 668 | + u64 resource_size, |
---|
| 669 | + u64 resource_id, |
---|
| 670 | + u64 parent_resource_id, |
---|
| 671 | + const struct devlink_resource_size_params *size_params); |
---|
| 672 | + |
---|
| 673 | +void dsa_devlink_resources_unregister(struct dsa_switch *ds); |
---|
| 674 | + |
---|
| 675 | +void dsa_devlink_resource_occ_get_register(struct dsa_switch *ds, |
---|
| 676 | + u64 resource_id, |
---|
| 677 | + devlink_resource_occ_get_t *occ_get, |
---|
| 678 | + void *occ_get_priv); |
---|
| 679 | +void dsa_devlink_resource_occ_get_unregister(struct dsa_switch *ds, |
---|
| 680 | + u64 resource_id); |
---|
| 681 | +struct devlink_region * |
---|
| 682 | +dsa_devlink_region_create(struct dsa_switch *ds, |
---|
| 683 | + const struct devlink_region_ops *ops, |
---|
| 684 | + u32 region_max_snapshots, u64 region_size); |
---|
| 685 | +struct devlink_region * |
---|
| 686 | +dsa_devlink_port_region_create(struct dsa_switch *ds, |
---|
| 687 | + int port, |
---|
| 688 | + const struct devlink_port_region_ops *ops, |
---|
| 689 | + u32 region_max_snapshots, u64 region_size); |
---|
| 690 | +void dsa_devlink_region_destroy(struct devlink_region *region); |
---|
| 691 | + |
---|
| 692 | +struct dsa_port *dsa_port_from_netdev(struct net_device *netdev); |
---|
| 693 | + |
---|
| 694 | +struct dsa_devlink_priv { |
---|
| 695 | + struct dsa_switch *ds; |
---|
| 696 | +}; |
---|
| 697 | + |
---|
| 698 | +static inline struct dsa_switch *dsa_devlink_to_ds(struct devlink *dl) |
---|
| 699 | +{ |
---|
| 700 | + struct dsa_devlink_priv *dl_priv = devlink_priv(dl); |
---|
| 701 | + |
---|
| 702 | + return dl_priv->ds; |
---|
| 703 | +} |
---|
| 704 | + |
---|
| 705 | +static inline |
---|
| 706 | +struct dsa_switch *dsa_devlink_port_to_ds(struct devlink_port *port) |
---|
| 707 | +{ |
---|
| 708 | + struct devlink *dl = port->devlink; |
---|
| 709 | + struct dsa_devlink_priv *dl_priv = devlink_priv(dl); |
---|
| 710 | + |
---|
| 711 | + return dl_priv->ds; |
---|
| 712 | +} |
---|
| 713 | + |
---|
| 714 | +static inline int dsa_devlink_port_to_port(struct devlink_port *port) |
---|
| 715 | +{ |
---|
| 716 | + return port->index; |
---|
| 717 | +} |
---|
524 | 718 | |
---|
525 | 719 | struct dsa_switch_driver { |
---|
526 | 720 | struct list_head list; |
---|
527 | 721 | const struct dsa_switch_ops *ops; |
---|
528 | 722 | }; |
---|
529 | 723 | |
---|
530 | | -#if IS_ENABLED(CONFIG_NET_DSA_LEGACY) |
---|
531 | | -/* Legacy driver registration */ |
---|
532 | | -void register_switch_driver(struct dsa_switch_driver *type); |
---|
533 | | -void unregister_switch_driver(struct dsa_switch_driver *type); |
---|
534 | | -struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev); |
---|
535 | | - |
---|
536 | | -#else |
---|
537 | | -static inline void register_switch_driver(struct dsa_switch_driver *type) { } |
---|
538 | | -static inline void unregister_switch_driver(struct dsa_switch_driver *type) { } |
---|
539 | | -static inline struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev) |
---|
540 | | -{ |
---|
541 | | - return NULL; |
---|
542 | | -} |
---|
543 | | -#endif |
---|
544 | 724 | struct net_device *dsa_dev_to_net_device(struct device *dev); |
---|
545 | 725 | |
---|
546 | 726 | /* Keep inline for faster access in hot path */ |
---|
547 | | -static inline bool netdev_uses_dsa(struct net_device *dev) |
---|
| 727 | +static inline bool netdev_uses_dsa(const struct net_device *dev) |
---|
548 | 728 | { |
---|
549 | 729 | #if IS_ENABLED(CONFIG_NET_DSA) |
---|
550 | 730 | return dev->dsa_ptr && dev->dsa_ptr->rcv; |
---|
.. | .. |
---|
552 | 732 | return false; |
---|
553 | 733 | } |
---|
554 | 734 | |
---|
555 | | -struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n); |
---|
| 735 | +static inline bool dsa_can_decode(const struct sk_buff *skb, |
---|
| 736 | + struct net_device *dev) |
---|
| 737 | +{ |
---|
| 738 | +#if IS_ENABLED(CONFIG_NET_DSA) |
---|
| 739 | + return !dev->dsa_ptr->filter || dev->dsa_ptr->filter(skb, dev); |
---|
| 740 | +#endif |
---|
| 741 | + return false; |
---|
| 742 | +} |
---|
| 743 | + |
---|
| 744 | +/* All DSA tags that push the EtherType to the right (basically all except tail |
---|
| 745 | + * tags, which don't break dissection) can be treated the same from the |
---|
| 746 | + * perspective of the flow dissector. |
---|
| 747 | + * |
---|
| 748 | + * We need to return: |
---|
| 749 | + * - offset: the (B - A) difference between: |
---|
| 750 | + * A. the position of the real EtherType and |
---|
| 751 | + * B. the current skb->data (aka ETH_HLEN bytes into the frame, aka 2 bytes |
---|
| 752 | + * after the normal EtherType was supposed to be) |
---|
| 753 | + * The offset in bytes is exactly equal to the tagger overhead (and half of |
---|
| 754 | + * that, in __be16 shorts). |
---|
| 755 | + * |
---|
| 756 | + * - proto: the value of the real EtherType. |
---|
| 757 | + */ |
---|
| 758 | +static inline void dsa_tag_generic_flow_dissect(const struct sk_buff *skb, |
---|
| 759 | + __be16 *proto, int *offset) |
---|
| 760 | +{ |
---|
| 761 | +#if IS_ENABLED(CONFIG_NET_DSA) |
---|
| 762 | + const struct dsa_device_ops *ops = skb->dev->dsa_ptr->tag_ops; |
---|
| 763 | + int tag_len = ops->overhead; |
---|
| 764 | + |
---|
| 765 | + *offset = tag_len; |
---|
| 766 | + *proto = ((__be16 *)skb->data)[(tag_len / 2) - 1]; |
---|
| 767 | +#endif |
---|
| 768 | +} |
---|
| 769 | + |
---|
| 770 | +#if IS_ENABLED(CONFIG_NET_DSA) |
---|
| 771 | +static inline int __dsa_netdevice_ops_check(struct net_device *dev) |
---|
| 772 | +{ |
---|
| 773 | + int err = -EOPNOTSUPP; |
---|
| 774 | + |
---|
| 775 | + if (!dev->dsa_ptr) |
---|
| 776 | + return err; |
---|
| 777 | + |
---|
| 778 | + if (!dev->dsa_ptr->netdev_ops) |
---|
| 779 | + return err; |
---|
| 780 | + |
---|
| 781 | + return 0; |
---|
| 782 | +} |
---|
| 783 | + |
---|
| 784 | +static inline int dsa_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, |
---|
| 785 | + int cmd) |
---|
| 786 | +{ |
---|
| 787 | + const struct dsa_netdevice_ops *ops; |
---|
| 788 | + int err; |
---|
| 789 | + |
---|
| 790 | + err = __dsa_netdevice_ops_check(dev); |
---|
| 791 | + if (err) |
---|
| 792 | + return err; |
---|
| 793 | + |
---|
| 794 | + ops = dev->dsa_ptr->netdev_ops; |
---|
| 795 | + |
---|
| 796 | + return ops->ndo_do_ioctl(dev, ifr, cmd); |
---|
| 797 | +} |
---|
| 798 | +#else |
---|
| 799 | +static inline int dsa_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, |
---|
| 800 | + int cmd) |
---|
| 801 | +{ |
---|
| 802 | + return -EOPNOTSUPP; |
---|
| 803 | +} |
---|
| 804 | +#endif |
---|
| 805 | + |
---|
556 | 806 | void dsa_unregister_switch(struct dsa_switch *ds); |
---|
557 | 807 | int dsa_register_switch(struct dsa_switch *ds); |
---|
| 808 | +struct dsa_switch *dsa_switch_find(int tree_index, int sw_index); |
---|
558 | 809 | #ifdef CONFIG_PM_SLEEP |
---|
559 | 810 | int dsa_switch_suspend(struct dsa_switch *ds); |
---|
560 | 811 | int dsa_switch_resume(struct dsa_switch *ds); |
---|
.. | .. |
---|
620 | 871 | #define BRCM_TAG_GET_QUEUE(v) ((v) & 0xff) |
---|
621 | 872 | |
---|
622 | 873 | |
---|
| 874 | +netdev_tx_t dsa_enqueue_skb(struct sk_buff *skb, struct net_device *dev); |
---|
623 | 875 | int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data); |
---|
624 | 876 | int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data); |
---|
625 | 877 | int dsa_port_get_phy_sset_count(struct dsa_port *dp); |
---|
626 | 878 | void dsa_port_phylink_mac_change(struct dsa_switch *ds, int port, bool up); |
---|
627 | 879 | |
---|
| 880 | +struct dsa_tag_driver { |
---|
| 881 | + const struct dsa_device_ops *ops; |
---|
| 882 | + struct list_head list; |
---|
| 883 | + struct module *owner; |
---|
| 884 | +}; |
---|
| 885 | + |
---|
| 886 | +void dsa_tag_drivers_register(struct dsa_tag_driver *dsa_tag_driver_array[], |
---|
| 887 | + unsigned int count, |
---|
| 888 | + struct module *owner); |
---|
| 889 | +void dsa_tag_drivers_unregister(struct dsa_tag_driver *dsa_tag_driver_array[], |
---|
| 890 | + unsigned int count); |
---|
| 891 | + |
---|
| 892 | +#define dsa_tag_driver_module_drivers(__dsa_tag_drivers_array, __count) \ |
---|
| 893 | +static int __init dsa_tag_driver_module_init(void) \ |
---|
| 894 | +{ \ |
---|
| 895 | + dsa_tag_drivers_register(__dsa_tag_drivers_array, __count, \ |
---|
| 896 | + THIS_MODULE); \ |
---|
| 897 | + return 0; \ |
---|
| 898 | +} \ |
---|
| 899 | +module_init(dsa_tag_driver_module_init); \ |
---|
| 900 | + \ |
---|
| 901 | +static void __exit dsa_tag_driver_module_exit(void) \ |
---|
| 902 | +{ \ |
---|
| 903 | + dsa_tag_drivers_unregister(__dsa_tag_drivers_array, __count); \ |
---|
| 904 | +} \ |
---|
| 905 | +module_exit(dsa_tag_driver_module_exit) |
---|
| 906 | + |
---|
| 907 | +/** |
---|
| 908 | + * module_dsa_tag_drivers() - Helper macro for registering DSA tag |
---|
| 909 | + * drivers |
---|
| 910 | + * @__ops_array: Array of tag driver strucutres |
---|
| 911 | + * |
---|
| 912 | + * Helper macro for DSA tag drivers which do not do anything special |
---|
| 913 | + * in module init/exit. Each module may only use this macro once, and |
---|
| 914 | + * calling it replaces module_init() and module_exit(). |
---|
| 915 | + */ |
---|
| 916 | +#define module_dsa_tag_drivers(__ops_array) \ |
---|
| 917 | +dsa_tag_driver_module_drivers(__ops_array, ARRAY_SIZE(__ops_array)) |
---|
| 918 | + |
---|
| 919 | +#define DSA_TAG_DRIVER_NAME(__ops) dsa_tag_driver ## _ ## __ops |
---|
| 920 | + |
---|
| 921 | +/* Create a static structure we can build a linked list of dsa_tag |
---|
| 922 | + * drivers |
---|
| 923 | + */ |
---|
| 924 | +#define DSA_TAG_DRIVER(__ops) \ |
---|
| 925 | +static struct dsa_tag_driver DSA_TAG_DRIVER_NAME(__ops) = { \ |
---|
| 926 | + .ops = &__ops, \ |
---|
| 927 | +} |
---|
| 928 | + |
---|
| 929 | +/** |
---|
| 930 | + * module_dsa_tag_driver() - Helper macro for registering a single DSA tag |
---|
| 931 | + * driver |
---|
| 932 | + * @__ops: Single tag driver structures |
---|
| 933 | + * |
---|
| 934 | + * Helper macro for DSA tag drivers which do not do anything special |
---|
| 935 | + * in module init/exit. Each module may only use this macro once, and |
---|
| 936 | + * calling it replaces module_init() and module_exit(). |
---|
| 937 | + */ |
---|
| 938 | +#define module_dsa_tag_driver(__ops) \ |
---|
| 939 | +DSA_TAG_DRIVER(__ops); \ |
---|
| 940 | + \ |
---|
| 941 | +static struct dsa_tag_driver *dsa_tag_driver_array[] = { \ |
---|
| 942 | + &DSA_TAG_DRIVER_NAME(__ops) \ |
---|
| 943 | +}; \ |
---|
| 944 | +module_dsa_tag_drivers(dsa_tag_driver_array) |
---|
628 | 945 | #endif |
---|
| 946 | + |
---|